[TOC]
# 更改
~~~
$user=User::find(1); //取出主鍵等于1的記錄
$user->user_name='jdxia';
$user->update(); //更新記錄
$bool=Student::where('id','>',10)->update(
['age'=>41]
);
~~~
用attributes
~~~
$post = Post::find(1);
$raw = $post->getAttributes();
$post->setRawAttributes($raw);
$post->save();
~~~
## 批量修改
~~~
User::where('nickname', 'LIKE', '%man%')->update([
'nickname' => 'Spider Man',
]);
~~~
> 這種方法不不會觸發updating、updated、saving、saved事件
# 查詢
這是在控制器寫,注意命名空間
~~~
//all 取出所有
$nm=Student::all();
//get 取出所有
$nm=Student::get();
//findOrFail 根據主鍵查詢,查找到了返回結果,查不到就報錯
$nm=Student::findorFail(3);
//連貫操作
$nm=Student::where('id','>','2')
->orderBy('age','desc')->first();
//chunk
$nm=Student::chunk(2,function($students){
print_r($students);
});
//聚合函數
$nm=Student::where('id','>',2)->max('age');
//findMany 根據ID數組查找多行數據
$user = User::findMany([1,2,3,4]);
foreach ($users as $user)
echo $user->id;
~~~
一些日期
~~~
$archives = Post::selectRaw('year(created_at) year, monthname(created_at) month, count(*) published')->groupBy('year','month')->orderByRaw('min(created_at) desc')->get();
$posts = Post::latest();
if ($month = request('month')) {
$posts->whereMonth('created_at',Carbon::parse($month)->month);
}
if ($year = request('year')) {
$posts->whereYear('created_at',$year);
}
$posts = $posts->get();
~~~
這里使用了 Laravel 提供的 whereDate 系列方法,同時,月份用 Carbon 進行轉換
## take offset取幾條數據
~~~
//take 取10條數句
$users = User::where('nickname', '=', 'nike')->orderBy('created', 'DESC')->take(10)->get();
//從第20行開始
$users = User::where('nickname', '=', 'nike')->orderBy('created', 'DESC')->take(10)->offset(20)->get();
~~~
**first 只取一條,并得到Model(非數據集)**
通過first可以將數據提取出首條并返回
`$user = User::where('id', '=', 1)->first();`
查詢數據庫有沒有這條記錄
~~~
//檢查用戶名是否存在
$user_exists=$this->where('username','=',$username)
->exists();
~~~
# ORM中添加,自定義時間戳及批量賦值
通過模型新增數據(涉及到自定義事件戳)
使用模型的create方法新增數據(涉及到批量賦值)
## 添加
~~~
//使用模型新增數據
$student=new Student();
$student->name='sean';
$student->age=18;
$bool=$student->save(); //返回布爾值
//上面會自動維護created_at和updated_at,不想用可以關掉
~~~
如果我們想存儲時間戳呢?記住字段的類型不要搞錯
在模型中寫
~~~
protected $table='stu';
//如果主鍵不是id,指定主鍵
protected $primarykey='id';
protected function getDateFormat()
{
return time();
}
~~~
如果查詢的時候想要時間戳怎么辦
模型中寫
~~~
protected function asDateTime($val)
{
return $val;
}
~~~
## create新增數據
批量添加數據,要在模型中寫
~~~
//默認表示模型的復數
protected $table='stu';
//如果主鍵不是id,指定主鍵
protected $primarykey='id';
//指定允許批量賦值的字段
protected $fillable=['name','age'];
//或者我們設置個這個guarded,就是不允許填充的字段為空數組[],這樣就可以填充進去了,就不用寫fillable了
protected $guarded=[];
~~~
這樣就可以用create批量添加的方法
~~~
$student=Student::create(
['name'=>'jdxia','age'=>18]
);
~~~
~~~
//以屬性查找用戶,有就查找,沒有就新增并取得新增的實例
$student=Student::firstOrCreate(
['name'=>'jdxia']
);
//firstOrNew()
//以屬性查找用戶,有就查找,沒有就顯示實例,如需保存需自行調用save
$student=Student::firstOrNew(
['name'=>'php']
);
$bool=$student->save();
~~~
# 刪除
通過模型刪除 通過主鍵值刪除 根據指定條件刪除
~~~
//通過模型刪除數據
$stu=Student::find(12);
$bool=$stu->delete();
//通過主鍵刪除
//單個刪除
$bool=Student::destroy(11);
//多個刪除
$bool=Student::destroy(9,10);
$bool=Student::destroy([5,6]);
//根據指定條件刪除
$bool=Student::where('id','>',3)->delete();
~~~
## 批量刪除
`User::where('nickname', 'LIKE', '%man%')->delete();`
>這種方法不不會觸發deleting、deleted事件
## 軟刪除 SoftDeletes
DB類會查出軟刪除
~~~
//SQL 庫中添加此字段
`deleted_at` timestamp NULL DEFAULT NULL,
//Model 中添加
use Illuminate\Database\Eloquent\SoftDeletes;
class User {
use SoftDeletes;
}
~~~
此時,執行刪除操作(delete destory)操作時,并非真正刪除數據,只是在deleted_at字段中做了刪除標記 此時通過find get where update等操作來獲取數據時,會自動忽略這些軟刪除數據
## 強制刪除
如需要強制刪除數據
~~~
$user = User::find(1);
$user->forceDelete();
~~~
## 查詢結果附帶軟刪除的數據
此時數據集中會附帶這些已被軟刪除的數據,后續操作時,需要自己甄別
`User::withTrashed()->where('nickname', 'Leo')->get();`
## 只返回軟刪除數據
`User::onlyTrashed()->where('nickname', 'Leo')->get();`
## 恢復軟刪除數據
~~~
$user = User::onlyTrashed()->find(12);
$user->restore();
~~~
# 銷毀結果集
~~~
$a=xx::where('id','=',12)->firstorFail();
$a->destory();
~~~
# 遞增和遞減
平時這么寫:
~~~
$article = Article::find($article_id);
$article->read_count++;
$article->save();
~~~
利用 increment 函數
~~~
$article = Article::find($article_id);
$article->increment('read_count');
~~~
當然可以傳入數字,不只是只增減 1:
~~~
Article::find($article_id)->increment('read_count');
Article::find($article_id)->increment('read_count', 10); // +10
Product::find($produce_id)->decrement('stock'); // -1
~~~
# WhereX
這里的 where 是前綴的作用,X表示的是我們的字段名,可以簡化我們的查詢寫法,平時都是這么寫的:
~~~
$users = User::where('approved', 1)->get();
~~~
簡便的寫法:
~~~
$users = User::whereApproved(1)->get();
~~~
具體實現主要利用 __call 方法。
public mixed __call ( string $name , array $arguments )
public static mixed __callStatic ( string $name , array $arguments )
在對象中調用一個不可訪問方法時,__call() 會被調用。
在靜態上下文中調用一個不可訪問方法時,__callStatic() 會被調用。
在 Query/Builder.php 中可以看出:
~~~
/**
* Handle dynamic method calls into the method.
*
* @param string $method
* @param array $parameters
* @return mixed
*
* @throws \BadMethodCallException
*/
public function __call($method, $parameters)
{
if (static::hasMacro($method)) {
return $this->macroCall($method, $parameters);
}
if (Str::startsWith($method, 'where')) {
return $this->dynamicWhere($method, $parameters);
}
$className = static::class;
throw new BadMethodCallException("Call to undefined method {$className}::{$method}()");
}
~~~
where 查詢方法都會調用函數:
~~~
return $this->dynamicWhere($method, $parameters);
~~~
~~~
/**
* Handles dynamic "where" clauses to the query.
*
* @param string $method
* @param string $parameters
* @return $this
*/
public function dynamicWhere($method, $parameters)
{
$finder = substr($method, 5);
$segments = preg_split(
'/(And|Or)(?=[A-Z])/', $finder, -1, PREG_SPLIT_DELIM_CAPTURE
);
// The connector variable will determine which connector will be used for the
// query condition. We will change it as we come across new boolean values
// in the dynamic method strings, which could contain a number of these.
$connector = 'and';
$index = 0;
foreach ($segments as $segment) {
// If the segment is not a boolean connector, we can assume it is a column's name
// and we will add it to the query as a new constraint as a where clause, then
// we can keep iterating through the dynamic method string's segments again.
if ($segment !== 'And' && $segment !== 'Or') {
$this->addDynamic($segment, $connector, $parameters, $index);
$index++;
}
// Otherwise, we will store the connector so we know how the next where clause we
// find in the query should be connected to the previous ones, meaning we will
// have the proper boolean connector to connect the next where clause found.
else {
$connector = $segment;
}
}
return $this;
}
~~~
繼續看 addDynamic 函數:
~~~
/**
* Add a single dynamic where clause statement to the query.
*
* @param string $segment
* @param string $connector
* @param array $parameters
* @param int $index
* @return void
*/
protected function addDynamic($segment, $connector, $parameters, $index)
{
// Once we have parsed out the columns and formatted the boolean operators we
// are ready to add it to this query as a where clause just like any other
// clause on the query. Then we'll increment the parameter index values.
$bool = strtolower($connector);
$this->where(Str::snake($segment), '=', $parameters[$index], $bool);
}
~~~
最后回到了` $this->where(Str::snake($segment), '=', $parameters[$index], $bool); `常規的 where 語句上;
同時,這過程我們可以發現 whereX 方法,不僅可以傳入一個字段,而且還可以傳入多個字段,用「And」或者 「Or」連接,且字段首字母用大寫「A~Z」。
# XorY methods
在平時有太多的寫法都是,先查詢,再判斷是否存在,然后再決定是輸出,還是創建。
如:
~~~
$user = User::where('email', $email)->first();
if (!$user) {
User::create([
'email' => $email
]);
}
~~~
一行代碼解決:
~~~
$user = User::firstOrCreate(['email' => $email]);
~~~
firstOrCreate 方法將會使用指定的字段 => 值對,來嘗試尋找數據庫中的記錄。如果在數據庫中找不到,`5.3`以下版本會使用屬性來添加一條記錄,`5.3`及以上版本則將使用第一個參數中的屬性以及可選的第二個參數中的屬性插入記錄
用法:
~~~php
User::firstOrCreate(['name' => 'Lisi']);
User::firstOrCreate(['name' => 'Lisi'], ['age' => 20]); // 5.3及以上版本支持
~~~
# find()
find() 函數通過主鍵獲取數據,平時都是獲取單數據,其實傳入的參數還可以是「主鍵數組」,獲取多 models。
~~~
$users = User::find([1,2,3]);
~~~
我們查看它的函數實現:
~~~
/**
* Find a model by its primary key.
*
* @param mixed $id
* @param array $columns
* @return \Illuminate\Database\Eloquent\Model|\Illuminate\Database\Eloquent\Collection|static[]|static|null
*/
public function find($id, $columns = ['*'])
{
if (is_array($id) || $id instanceof Arrayable) {
return $this->findMany($id, $columns);
}
return $this->whereKey($id)->first($columns);
}
~~~
首先判斷的是 id 是不是 array,如果是的話,則執行 findMany 函數:
~~~
/**
* Find multiple models by their primary keys.
*
* @param \Illuminate\Contracts\Support\Arrayable|array $ids
* @param array $columns
* @return \Illuminate\Database\Eloquent\Collection
*/
public function findMany($ids, $columns = ['*'])
{
if (empty($ids)) {
return $this->model->newCollection();
}
return $this->whereKey($ids)->get($columns);
}
~~~
獲取的結果是一個 Collection 類型。
- 配置
- composer安裝
- composer用法
- composer版本約束表達
- phpstorm
- sftp文件同步
- php類型約束
- laradock
- 配置文件緩存詳解
- git
- 自定義函數
- 核心概念
- IOC
- 服務提供者
- Facade
- 契約
- 生命周期
- 路由
- 請求
- 命名路由
- 路由分組
- 資源路由
- 控制器路由
- 響應宏
- 響應
- Command
- 創建命令
- 定時任務
- console路由
- 執行用戶自定義的定時任務
- artisan命令
- 中間件
- 創建中間件
- 使用中間件
- 前置和后置
- 詳細介紹
- 訪問次數限制
- 為 VerifyCsrfToken 添加過濾條件
- 單點登錄
- 事件
- 創建
- ORM
- 簡介
- DB類
- 配置
- CURD
- queryScope和setAttribute
- 查看sql執行過程
- 關聯關系
- 一對一
- 一對多
- 多對多
- 遠程關聯
- 多態一對多
- 多態多對多
- 關聯數據庫的調用
- withDefault
- 跨模型更新時間戳
- withCount,withSum ,withAvg, withMax,withMin
- SQL常見操作
- 模型事件
- 模型事件詳解
- 模型事件與 Observer
- deleted 事件未被觸發
- model validation
- ORM/代碼片段
- Repository模式
- 多重where語句
- 中間表類型轉換
- Collection集合
- 新增的一些方法
- 常見用法
- 求和例子
- 機場登機例子
- 計算github活躍度
- 轉化評論格式
- 計算營業額
- 創建lookup數組
- 重新組織出表和字段關系并且字段排序
- 重構循環
- 其他例子
- 其他問題一
- 去重
- 第二個數組按第一個數組的鍵值排序
- 搜索ES
- 安裝
- 表單
- Request
- sessiom
- Response
- Input
- 表單驗證
- 簡介
- Validator
- Request類
- 接口中的表單驗證
- Lumen 中自定義表單驗證返回消息
- redis
- 廣播事件
- 發布訂閱
- 隊列
- 守護進程
- redis隊列的坑
- beanstalkd
- rabbitmq
- redis隊列
- 日志模塊
- 錯誤
- 日志詳解
- 數據填充與遷移
- 生成數據
- 數據填充seed
- migrate
- 常見錯誤
- Blade模板
- 流程控制
- 子視圖
- URL
- 代碼片段
- Carbon時間類
- 一些用法
- 郵件
- 分頁
- 加密解密
- 緩存
- 文件上傳
- 優化
- 隨記
- 嵌套評論
- 判斷字符串是否是合法的 json 字符串
- 單元測試
- 計算出兩個日期的diff
- 自定義一個類文件讓composer加載
- 時間加減
- 對象數組互轉方法
- 用戶停留過久自動退出登錄
- optional 輔助方法
- 文件下載
- Api
- Dingo api
- auth.basic
- api_token
- Jwt-Auth
- passport
- Auth
- Authentication 和 Authorization
- Auth Facade
- 授權策略
- Gates
- composer包
- debug包
- idehelp包
- image處理
- 驗證碼
- jq插件
- 第三方登錄
- 第三方支付
- log顯示包
- 微信包
- xss過濾
- Excel包
- MongoDB
- php操作
- 聚合查詢
- 發送帶附件郵件
- 中文轉拼音包
- clockwork網頁調試
- emoji表情
- symfony組件
- swooletw/laravel-swoole
- 常見問題
- 跨域問題
- Laravel隊列優先級的一個坑
- cache:clear清除緩存問題
- .env無法讀取
- 源碼相關基礎知識
- __set和__get
- 依賴注入、控制反轉和依賴倒置原則
- 控制反轉容器(Ioc Container)
- 深入服務容器
- call_user_func
- compact
- 中間件簡易實現
- array_reduce
- 中間件實現代碼
- Pipeline管道操作
- composer自動加載
- redis延時隊列
- 了解laravel redis隊列
- cli
- 源碼解讀
- Facade分析
- Facade源碼分析
- IOC服務容器
- 中間件原理
- 依賴注入淺析
- 微信
- 微信公眾號
- 常用接收消息
- 6大接收接口
- 常用被動回復消息
- 接口調用憑證
- 自定義菜單
- 新增素材
- 客服消息
- 二維碼
- 微信語音
- LBS定位
- 網頁授權
- JSSDK
- easywechat
- 小程序
- 小程序配置app.json