跨域請求api,使用自封裝的類
自封裝curl類
/**
* @param $url 請求網址
* @param bool $params 請求引數
* @param int $ispost 請求方式
* @param int $https https協議
* @return bool|mixed
*/
public static function get($url, $params = false, $ispost = 0, $https = 0)
{
$httpInfo = array();
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_1);
curl_setopt($ch, CURLOPT_USERAGENT, 'Mozilla/5.0 (Windows NT 10.0; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/41.0.2272.118 Safari/537.36');
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
if ($https) {
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); // 對認證證照來源的檢查
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, FALSE); // 從證照中檢查SSL加密演算法是否存在
}
if ($ispost) {
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $params);
curl_setopt($ch, CURLOPT_URL, $url);
} else {
if ($params) {
if (is_array($params)) {
$params = http_build_query($params);
}
curl_setopt($ch, CURLOPT_URL, $url . '?' . $params);
} else {
curl_setopt($ch, CURLOPT_URL, $url);
}
}
$response = curl_exec($ch);
if ($response === FALSE) {
//echo "cURL Error: " . curl_error($ch);
return false;
}
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
$httpInfo = array_merge($httpInfo, curl_getinfo($ch));
curl_close($ch);
return $response;
}
原文連結:部落格:好用的 CURL 類
呼叫
$result = curl::get("http://172.16.112.3/api.php",'', true);
$index=json_decode($result);
return $index;
原生ajax實現跨域
$.ajax({
async: true,
url: "http://172.16.112.3/api.php",
type: "GET",
dataType: "jsonp", // 返回的資料型別,設定為JSONP方式
jsonp: 'callback', //指定一個查詢引數名稱來覆蓋預設的 jsonp 回撥引數名 callback
jsonpCallback: 'handleResponse', //設定回撥函式名
success: function (response, status, xhr) {
console.log('狀態為:' + status + ',狀態是:' + xhr.statusText);
console.log(response);
}
});
原生js實現跨域
window.onload = function () {
function jsonp(obj) {
//定義一個處理Jsonp返回資料的回撥函式
window["callback"] = function (object) {
obj.success(object);
}
var script = document.createElement("script");
//組合請求URL
script.src = obj.url + "?callback=callback";
for (key in obj.data) {
script.src += "&" + key + "=" + obj.data[key];
}
//將建立的新節點新增到BOM樹上
document.getElementsByTagName("body")[0].appendChild(script);
}
jsonp({
url: "http://172.16.112.3/api.php",
success: function (obj) {
console.log(obj);
}
});
}
使用Guzzle
參考文件: https://guzzle-cn.readthedocs.io/zh_CN/lat...
具體的實現
setAttribute() 這一行是強制性的,它會告訴 PDO 禁用模擬預處理語句,並使用 real parepared statements 。這可以確保SQL語句和相應的值在傳遞到mysql伺服器之前是不會被PHP解析的(禁止了所有可能的惡意SQL隱碼攻擊)。雖然你可以配置檔案中設定 字符集的屬性(charset=utf8),但是需要格外注意的是,老版本的 PHP( < 5.3.6)在DSN中是忽略字元引數的。
我們來看一段完整的程式碼使用例項:
$user=$_POST['user']; $pass=$_POST['pass'];
$dbh = new \PDO("mysql:host=localhost; dbname=zz", "root", "root");
$dbh->setAttribute(\PDO::ATTR_EMULATE_PREPARES, false);
//禁用prepared statements的模擬效果
// $dbh->exec ("set names 'utf8'");
$sql="select * from test where user=? and pass=?";
$stmt = $dbh->prepare($sql);
$exeres = $stmt->execute(array($user, $pass));
if ($exeres) {
//while條件為真時,輸出$row,
while
($row = $stmt->fetch(\PDO::FETCH_ASSOC)){
print_r($row);die();
} //失敗輸出登入失敗
print_r("登入失敗");die();
}
當呼叫 prepare() 時,查詢語句已經傳送給了資料庫伺服器,此時只有佔位符 ? 傳送過去,沒有使用者提交的資料;當呼叫到 execute()時,使用者提交過來的值才會傳送給資料庫,他們是分開傳送的,兩者獨立的,SQL攻擊者沒有一點機會。
注意事項
以下幾種情況,PDO並不能幫助你防範SQL隱碼攻擊
你不能讓佔位符 ? 代替一組值,如:
SELECT * FROM blog WHERE userid IN ( ? );
你不能讓佔位符代替資料表名或列名,如:
SELECT * FROM blog ORDER BY ?;
你不能讓佔位符 ? 代替任何其他SQL語法,如:
SELECT EXTRACT( ? FROM datetime_column) AS variable_datetime_element FROM blog;
模擬請求
$postData=file_get_contents('C:\Users\ASUS\Pictures\Saved Pictures\2.jpg');
$curl = curl_init();
curl_setopt($curl, CURLOPT_URL, 'http://www.think.hk/upload1');
curl_setopt($curl, CURLOPT_USERAGENT,'Opera/9.80 (Windows NT 6.2; Win64; x64) Presto/2.12.388 Version/12.15');
curl_setopt($curl, CURLOPT_SSL_VERIFYPEER, false); // stop verifying certificate
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);
curl_setopt($curl, CURLOPT_POST, true);
curl_setopt($curl, CURLOPT_HTTPHEADER, array('Content-Type: application/x-www-form-urlencoded'));//注意加這行程式碼
curl_setopt($curl, CURLOPT_POSTFIELDS, $postData);
curl_setopt($curl, CURLOPT_FOLLOWLOCATION, true);
$r = curl_exec($curl);
curl_close($curl);
print_r($r);
接收二進位制
$xmlstr = file_get_contents('php://input') ? file_get_contents('php://input') : gzuncompress($GLOBALS['HTTP_RAW_POST_DATA']);//得到post過來的二進位制原始資料
//echo $xmlstr;die;
$filename=time().'.png';
$info=file_put_contents($filename,$xmlstr);
if ($info) {
$result = [
'error' => '成功',
'url' => $filename
];
} else {
$result = ['error' => 1,
'message' => 404
];
}
return json_encode($result);
生成資源
php artisan make:resource Product
php artisan make:resource Admin
建立model以及遷移檔案
php artisan make:model Product -mc
php artisan make:model Admin -mc
遷移表
php artisan migrate
生成控制器
php artisan make:controller ProductController
資源類的操作
<?php
namespace App\Http\Resources;
use Illuminate\Http\Resources\Json\JsonResource;
use App\Http\Resources\Admin as Adminss;
use App\Admin as AdminModel;
class Product extends JsonResource
{
/**
* Transform the resource into an array.
*
* @param \Illuminate\Http\Request $request
* @return array
*/
public $preserveKeys = true;
public function toArray($request)
{
return [
'data' => [
'id' => $this->id,
'name' => $this->name,
'price' => $this->price,
'username'=>Adminss::collection(AdminModel::where('id',$this->id)->get()),//獲取id相同的amdin表欄位
'created_at' => $this->created_at,
'updated_at' => $this->updated_at,
],
];
}
}
封裝json返回資料格式 我使用了trait 並沒有使用api那個
<?php
namespace App\Http\api\messages;
trait ApiMessages{
public function backSuccessMsg($data,$SuccessStatus,$falseStatus){
if ($data){
return response()->json([
'status' => 'success',
'status_code'=>$SuccessStatus,
'msg' => '呼叫成功',
'data'=>[
"status"=>100,
"data"=>$data]
]);
}else{
return response()->json([
'status' => 'false',
'status_code'=>$falseStatus,
'msg' => '呼叫失敗',
'data'=>[
"status"=>101]
]);
}
}
}
路由書寫 api.php編寫
Route::get('/products/{id}', 'ProductController@show');
控制器的書寫
<?php
namespace App\Http\Controllers;
use App\Product;
use Illuminate\Http\Request;
use App\Http\Resources\Product as ProductResource;
class ProductController extends Controller
{
use \App\Http\api\messages\ApiMessages;
public function show ()
{
$data=ProductResource::collection(Product::all()->keyBy->id);
return $this->backSuccessMsg($data,$SuccessStatus=100,$FalseStatus=101);
}
}
觸發父級的時間戳
在子模型更新時,可以觸發父模型的時間戳。例如 Comment
屬於 Post
,有時更新子模型導致更新父模型時間戳非常有用。
例如,當 Comment
模型被更新時,您要自動觸發父級 Post
模型的 updated_at
時間戳的更新。Eloquent
讓它變得簡單,只需新增一個包含子模型關係名稱的 touch
屬性。
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Comment extends Model
{
/**
* 涉及到的所有關聯關係。
*
* @var array
*/
protected $touches = ['post'];
/**
* 獲取評論所屬的文章。
*/
public function post()
{
return $this->belongsTo('App\Post');
}
}
預載入精確的列
在使用預載入時,可以從關係中獲取指定的列。
$users = App\Book::with('author:id,name')->get();
為單個請求驗證使用者身份
你可以使用 Auth::once()
來為單個請求驗證使用者的身份,此方法不會使用 Cookie
會話。這意味著此方法可能有助於構建無狀態 API 。
if (Auth::once($credentials)) {
//
}
重定向到帶有引數的控制器方法中
你不僅可以將 redirect()
方法用於使用者特定的 URL 或者路由中,還可以用於控制器中帶有引數的方法中
return redirect()->action('SomeController@method', ['param' => $value]);
如何使用 withDefault() 避免在關係中出現的錯誤
當一個關係被呼叫時,如果它不存在,則會出現致命的錯誤,例如 $post->user->name
,可以使用withDefault()
來避免。
/** 獲取文章作者 */
public function user()
{
return $this->belongsTo('App\User')->withDefault();
}
在模版中兩個平級的 $loop 變數
在 blade
的 foreach
中,即使在兩次迴圈中,依然可以通過使用 $loop
變數來獲取父級變數。
@foreach ($users as $user)
@foreach ($user->posts as $post)
@if ($loop->parent->first)
This is first iteration of the parent loop.
@endif
@endforeach
@endforeach
修改查詢結果
在執行 Eloqument
查詢後,你可以使用 map()
來修改行。
$users = User::where('role_id', 1)->get()->map(function (User $user) {
$user->some_column = some_function($user);
return $user;
});
輕鬆的使用 dd()
在 Eloqument
的最後加上 $test->dd()
,來代替 dd($result)
。
// 優化前
$users = User::where('name', 'Taylor')->get();
dd($users);
// 優化後
$users = User::where('name', 'Taylor')->get()->dd();
Use hasMany to saveMany.
如果有 hasMany()
關聯關係,和想要從父類物件中儲存許多子類物件,可以使用 saveMany()
來達到你想要的效果。
$post = Post::find(1);
$post->comments()->saveMany([
new Comment(['message' => 'First comment']),
new Comment(['message' => 'Second comment']),
]);
在 Model::all() 中指定列
當你使用 Eloqument
的 Model::all()
時,你可以指定要返回的列。
$users = User::all(['id', 'name', 'email']);
Blade 中的 @auth
你可以使用 @auth
指令來代替 if
語句來檢查使用者是否經過身份驗證。
典型的方法:
@if(auth()->user()) // The user is authenticated. @endif
簡短的方法:
@auth
// The user is authenticated.
@endauth
預覽郵件而不傳送
如果你使用 Mailables 來傳送你的郵件,你可以預覽它們而不傳送出去。
Route::get('/mailable', function () {
$invoice = App\Invoice::find(1);
return new App\Mail\InvoicePaid($invoice);
});
hasMany 的特定檢查
在 Eloquent
的 hasMany()
關係中,你可以篩選出具有 n 個子記錄數量的記錄。
// Author -> hasMany(Book::class)
$authors = Author::has('books', '>', 5)->get();
恢復多個軟刪除
如果記錄使用了軟刪除,那麼你就可以一次恢復多條軟刪除記錄。
Post::withTrashed()->where('author_id', 1)->restore();
帶時區的遷移列
遷移檔案不僅有 timestamps()
時間戳,還有 timestampsTz()
帶有時區的時間戳。
Schema::create('employees', function (Blueprint $table) {
$table->increments('id');
$table->string('name');
$table->string('email');
$table->timestampsTz();
});
檢視檔案是否存在?
你知道還可以檢查檢視檔案是否存在嗎?
if (view()->exists('custom.page')) {
// Load the view
}
組中的路由組
在路由檔案中,你可以為一個路由組創造一個組,還可以為其指定特定的中介軟體。
Route::group(['prefix' => 'account', 'as' => 'account.'], function() {
Route::get('login', 'AccountController@login');
Route::get('register', 'AccountController@register');
Route::group(['middleware' => 'auth'], function() {
Route::get('edit', 'AccountController@edit');
});
});
Eloquent 中的日期時間方法
whereDay()
, whereMonth()
, whereYear()
, whereDate()
, whereTime()
這些方法皆為Eloquent
中檢查日期的方法。
$products = Product::whereDate('created_at', '2018-01-31')->get();
$products = Product::whereMonth('created_at', '12')->get();
$products = Product::whereDay('created_at', '31')->get();
$products = Product::whereYear('created_at', date('Y'))->get();
$products = Product::whereTime('created_at', '=', '14:13:58')->get();
在 Eloquent 關係中使用 orderBy()
你可以在 Eloquent
關係中直接指定 orderBy()
。
public function products()
{
return $this->hasMany(Product::class);
}
public function productsByName()
{
return $this->hasMany(Product::class)->orderBy('name');
}
無符號整型
對於遷移的外來鍵,不要使用 integer()
, 而是使用 unsignedInteger()
或者是 integer()->unsigned()
,否則將會出現一系列的錯誤。
Schema::create('employees', function (Blueprint $table) {
$table->unsignedInteger('company_id');
$table->foreign('company_id')->references('id')->on('companies');
});
轉自微信公眾號 : php中文網最新課程
一些符號
PHP中.=和+=
.=
通俗的說,就是累積。
$a = 'a'; //賦值
$b = 'b'; //賦值
$c = 'c'; //賦值
$c .= $a;
$c .= $b;
echo $c; 就會顯示 cab
+=
意思是:左邊的變數的值加上右邊的變數的值再賦給左邊的變數。
??和?:的區別
$a=$c??$b;
等同於 $a=isset($c)?$c:$b;
$a=$c?:$b;
等同於 $a=$c?$c:$b;
swoole
安裝swoole擴充
php擴充套件包地址:pecl.php.net\
swoole是一個PHP的非同步、並行、高效能網路通訊引擎,使用純C語言編寫,提供了PHP語言的非同步多執行緒伺服器,非同步TCP/UDP網路客戶端,非同步MySQL,非同步Redis,資料庫連線池,AsyncTask,訊息佇列,毫秒定時器,非同步檔案讀寫,非同步DNS查詢。 Swoole內建了Http/WebSocket伺服器端/客戶端、Http2.0伺服器端。\
Swoole可以廣泛應用於網際網路、行動通訊、企業軟體、雲端計算、網路遊戲、物聯網(IOT)、車聯網、智慧家居等領域。 使用PHP+Swoole作為網路通訊框架,可以使企業IT研發團隊的效率大大提升,更加專注於開發創新產品。
注意事項:\
1、server.php中的ip地址必須是外網可訪問地址 123.57.232.99,不能為localhost
1、安裝
# wget https://github.com/swoole/swoole-src/archive/swoole-1.7.6-stable.tar.gz
# tar zxvf swoole-1.7.6-stable.tar.gz
# cd swoole-1.7.6-stable
# phpize
# ./configure
# make && make install**
提示:
Build complete.
Don’t forget to run ‘make test’.
Installing shared extensions: /usr/lib64/php/modules/
說明安裝成功
2、php載入swoole擴充套件
extension=/xxx/xxx/php5.6/lib/php/extensions/no-debug-non-zts-20131226/swoole.so
3、重啟服務
service php-fpm restart
service nginx restart
4、測試,檢視phpinfo資訊,如下圖所示:
5、程式碼測試
server.php程式碼:
# telnet 123.57.232.99 55152
Trying 123.57.232.99…
Connected to 123.57.232.99.
Escape character is ‘^]’.
rr\
Swoole: rr\
測試\
Swoole: 測試\
日積月累,謝謝大佬