[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