1、简介
数据库查询构建器提供了一个方便的、平滑的接口来创建和运行数据库查询。查询构建器可以用于执行应用中大部分数据库操作,并且能够在支持的所有数据库系统上工作。
注意:Laravel 查询构建器使用 PDO 参数绑定来避免 SQL 注入攻击,不再需要过滤传递到绑定的字符串。
2、获取结果集
从一张表中取出所有行
在查询之前,使用 DB门面的 table方法, table方法为给定表返回一个查询构建器,允许你在查询上链接更多约束条件并最终返回查询结果。在本例中,我们使用 get方法获取表中所有记录:
<?phpnamespace App\Http\Controllers;use DB;use App\Http\Controllers\Controller;class UserController extends Controller{ /** * 显示用户列表 * * @return Response */ public function index() { $users = DB::table('users')->get(); return view('user.index', ['users' => $users]); }}
和原生查询一样, get方法返回结果集的数组,其中每一个结果都是PHP对象的 StdClass实例。你可以像访问对象的属性一样访问列的值:
foreach ($users as $user) { echo $user->name;}
从一张表中获取一行/一列
如果你只是想要从数据表中获取一行数据,可以使用 first方法,该方法将会返回单个 StdClass对象:
$user = DB::table('users')->where('name', 'John')->first();echo $user->name;
如果你不需要完整的一行,可以使用value方法从结果中获取单个值,该方法会直接返回指定列的值:
$email = DB::table('users')->where('name', 'John')->value('email');
从一张表中获取组块结果集
如果你需要处理成千上百条数据库记录,可以考虑使用 chunk方法,该方法一次获取结果集的一小块,然后填充每一小块数据到要处理的闭包,该方法在编写处理大量数据库记录的 Artisan 命令的时候非常有用。比如,我们可以将处理全部 users 表数据处理成一次处理 100 记录的小组块:
DB::table('users')->chunk(100, function($users) { foreach ($users as $user) { // }});
你可以通过从闭包函数中返回false来中止组块的运行:
DB::table('users')->chunk(100, function($users) { // 处理结果集... return false;});
获取数据列值列表
如果想要获取包含单个列值的数组,可以使用 lists方法,在本例中,我们获取所有 title的数组:
$titles = DB::table('roles')->lists('title');foreach ($titles as $title) { echo $title;}
在还可以在返回数组中为列值指定更多的自定义键(该自定义键必须是该表的其它字段列名,否则会报错):
$roles = DB::table('roles')->lists('title', 'name');foreach ($roles as $name => $title) { echo $title;}
聚合函数
队列构建器还提供了很多聚合方法,比如 count, max, min, avg, 和 sum,你可以在构造查询之后调用这些方法:
$users = DB::table('users')->count();$price = DB::table('orders')->max('price');
当然,你可以联合其它查询子句和聚合函数来构建查询:
$price = DB::table('orders') ->where('finalized', 1) ->avg('price');
3、查询(Select)
指定查询子句
当然,我们并不总是想要获取数据表的所有列,使用 select方法,你可以为查询指定自定义的 select子句:
$users = DB::table('users')->select('name', 'email as user_email')->get();
distinct方法允许你强制查询返回不重复的结果集:
$users = DB::table('users')->distinct()->get();
如果你已经有了一个查询构建器实例并且希望添加一个查询列到已存在的 select子句,可以使用 addSelect方法:
$query = DB::table('users')->select('name');$users = $query->addSelect('age')->get();
原生表达式
有时候你希望在查询中使用原生表达式,这些表达式将会以字符串的形式注入到查询中,所以要格外小心避免被 SQL 注入。想要创建一个原生表达式,可以使用 DB::raw方法:
$users = DB::table('users') ->select(DB::raw('count(*) as user_count, status')) ->where('status', '<>', 1) ->groupBy('status') ->get();
4、连接(Join)
内连接(等值连接)
查询构建器还可以用于编写基本的SQL“内连接”,你可以使用查询构建器实例上的 join方法,传递给 join方法的第一次参数是你需要连接到的表名,剩余的其它参数则是为连接指定的列约束,当然,正如你所看到的,你可以在单个查询中连接多张表:
$users = DB::table('users') ->join('contacts', 'users.id', '=', 'contacts.user_id') ->join('orders', 'users.id', '=', 'orders.user_id') ->select('users.*', 'contacts.phone', 'orders.price') ->get();
左连接
如果你是想要执行“左连接”而不是“内连接”,可以使用 leftJoin方法。该方法和 join方法的使用方法一样:
$users = DB::table('users') ->leftJoin('posts', 'users.id', '=', 'posts.user_id') ->get();
高级连接语句
你还可以指定更多的高级连接子句,传递一个闭包到 join方法作为该方法的第2个参数,该闭包将会返回允许你指定 join子句约束的 JoinClause对象:
DB::table('users') ->join('contacts', function ($join) { $join->on('users.id', '=', 'contacts.user_id')->orOn(...); }) ->get();
如果你想要在连接中使用“where”风格的子句,可以在查询中使用 where和 orWhere方法。这些方法将会将列和值进行比较而不是列和列进行比较:
DB::table('users') ->join('contacts', function ($join) { $join->on('users.id', '=', 'contacts.user_id') ->where('contacts.user_id', '>', 5); }) ->get();
5、联合(Union)
查询构建器还提供了一条“联合”两个查询的快捷方式,比如,你要创建一个独立的查询,然后使用 union方法将其和第二个查询进行联合:
$first = DB::table('users') ->whereNull('first_name');$users = DB::table('users') ->whereNull('last_name') ->union($first) ->get();
unionAll方法也是有效的,并且和 union有同样的使用方法。
6、Where子句
简单where子句
使用查询构建器上的 where方法可以添加 where子句到查询中,调用 where最基本的方法需要三个参数,第一个参数是列名,第二个参数是一个数据库系统支持的任意操作符,第三个参数是该列要比较的值。
例如,下面是一个验证“votes”列的值是否等于100的查询:
$users = DB::table('users')->where('votes', '=', 100)->get();
为了方便,如果你只是简单比较列值和给定数值是否相等,可以将数值直接作为 where方法的第二个参数:
$users = DB::table('users')->where('votes', 100)->get();
当然,你可以使用其它操作符来编写 where子句:
$users = DB::table('users') ->where('votes', '>=', 100) ->get();$users = DB::table('users') ->where('votes', '<>', 100) ->get();$users = DB::table('users') ->where('name', 'like', 'T%') ->get();
or
你可以通过方法链将多个 where约束链接到一起,也可以添加 or子句到查询, orWhere方法和 where方法接收参数一样:
$users = DB::table('users') ->where('votes', '>', 100) ->orWhere('name', 'John') ->get();
更多Where子句
whereBetween
whereBetween方法验证列值是否在给定值之间:
$users = DB::table('users') ->whereBetween('votes', [1, 100])->get();
whereNotBetween
whereNotBetween方法验证列值不在给定值之间:
$users = DB::table('users') ->whereNotBetween('votes', [1, 100]) ->get();
whereIn/whereNotIn
whereIn方法验证给定列的值是否在给定数组中:
$users = DB::table('users') ->whereIn('id', [1, 2, 3]) ->get();
whereNotIn方法验证给定列的值不在给定数组中:
$users = DB::table('users') ->whereNotIn('id', [1, 2, 3]) ->get();
whereNull/whereNotNull
whereNull方法验证给定列的值为NULL:
$users = DB::table('users') ->whereNull('updated_at') ->get();
whereNotNull方法验证给定列的值不是NULL:
$users = DB::table('users') ->whereNotNull('updated_at') ->get();
高级Where子句
参数 分组
有时候你需要创建更加高级的 where子句比如“where exists”或者嵌套的参数分组。Laravel查询构建器也可以处理这些。作为开始,让我们看一个在括号中进行分组约束的例子:
DB::table('users') ->where('name', '=', 'John') ->orWhere(function ($query) { $query->where('votes', '>', 100) ->where('title', '<>', 'Admin'); }) ->get();
正如你所看到的,传递闭包到 orWhere方法构造查询构建器来开始一个约束分组,,该闭包将会获取一个用于设置括号中包含的约束的查询构建器实例。上述语句等价于下面的SQL:
select * from users where name = 'John' or (votes > 100 and title <> 'Admin')
exists语句
whereExists方法允许你编写 where existSQL子句, whereExists方法接收一个闭包参数,该闭包获取一个查询构建器实例从而允许你定义放置在“exists”子句中的查询:
DB::table('users') ->whereExists(function ($query) { $query->select(DB::raw(1)) ->from('orders') ->whereRaw('orders.user_id = users.id'); }) ->get();
上述查询等价于下面的SQL语句:
select * from userswhere exists ( select 1 from orders where orders.user_id = users.id)
7、排序、分组、限定
orderBy
orderBy方法允许你通过给定列对结果集进行排序, orderBy的第一个参数应该是你希望排序的列,第二个参数控制着排序的方向——asc或desc:
$users = DB::table('users') ->orderBy('name', 'desc') ->get();
groupBy / having / havingRaw
groupBy和 having方法用于对结果集进行分组, having方法和 where方法的用法类似:
$users = DB::table('users') ->groupBy('account_id') ->having('account_id', '>', 100) ->get();
havingRaw方法可以用于设置原生字符串作为 having子句的值,例如,我们要找到所有售价大于 $2500的部分:
$users = DB::table('orders') ->select('department', DB::raw('SUM(price) as total_sales')) ->groupBy('department') ->havingRaw('SUM(price) > 2500') ->get();
skip / take
想要限定查询返回的结果集的数目,或者在查询中跳过给定数目的结果,可以使用 skip和 take方法:
$users = DB::table('users')->skip(10)->take(5)->get();
8、插入(Insert)
查询构建器还提供了 insert方法来插入记录到数据表。 insert方法接收数组形式的列名和值进行插入操作:
DB::table('users')->insert( ['email' => 'john@example.com', 'votes' => 0]);
你甚至可以一次性通过传入多个数组来插入多条记录,每个数组代表要插入数据表的记录:
DB::table('users')->insert([ ['email' => 'taylor@example.com', 'votes' => 0], ['email' => 'dayle@example.com', 'votes' => 0]]);
自增ID
如果数据表有自增ID,使用 insertGetId方法来插入记录将会返回ID值:
$id = DB::table('users')->insertGetId( ['email' => 'john@example.com', 'votes' => 0]);
注意:当使用 PostgresSQL时 insertGetId方法默认自增列被命名为 id,如果你想要从其他“序列”获取ID,可以将序列名作为第二个参数传递到 insertGetId方法。
9、更新(Update)
当然,除了插入记录到数据库,查询构建器还可以通过使用 update方法更新已有记录。 update方法和 insert方法一样,接收列和值的键值对数组包含要更新的列,你可以通过 where子句来对 update查询进行约束:
DB::table('users') ->where('id', 1) ->update(['votes' => 1]);
增加/减少
查询构建器还提供了方便增减给定列名数值的方法。相较于编写 update语句,这是一条捷径,提供了更好的体验和测试接口。
这两个方法都至少接收一个参数:需要修改的列。第二个参数是可选的,用于控制列值增加/减少的数目。
DB::table('users')->increment('votes');DB::table('users')->increment('votes', 5);DB::table('users')->decrement('votes');DB::table('users')->decrement('votes', 5);
在操作过程中你还可以指定额外的列进行更新:
DB::table('users')->increment('votes', 1, ['name' => 'John']);
10、删除(Delete)
当然,查询构建器还可以通过 delete方法从表中删除记录:
DB::table('users')->delete();
在调用 delete方法之前可以通过添加 where子句对 delete语句进行约束:
DB::table('users')->where('votes', '<', 100)->delete();
如果你希望清除整张表,也就是删除所有列并将自增ID置为0,可以使用 truncate方法:
DB::table('users')->truncate();
11、悲观锁
查询构建器还包含一些方法帮助你在select语句中实现“悲观锁”。可以在查询中使用 sharedLock方法从而在运行语句时带一把”共享锁“。共享锁可以避免被选择的行被修改直到事务提交:
DB::table('users')->where('votes', '>', 100)->sharedLock()->get();
此外你还可以使用 lockForUpdate方法。“for update”锁避免选择行被其它共享锁修改或删除:
DB::table('users')->where('votes', '>', 100)->lockForUpdate()->get();

PHP在現代Web開發中仍然重要,尤其在內容管理和電子商務平台。 1)PHP擁有豐富的生態系統和強大框架支持,如Laravel和Symfony。 2)性能優化可通過OPcache和Nginx實現。 3)PHP8.0引入JIT編譯器,提升性能。 4)雲原生應用通過Docker和Kubernetes部署,提高靈活性和可擴展性。

PHP適合web開發,特別是在快速開發和處理動態內容方面表現出色,但不擅長數據科學和企業級應用。與Python相比,PHP在web開發中更具優勢,但在數據科學領域不如Python;與Java相比,PHP在企業級應用中表現較差,但在web開發中更靈活;與JavaScript相比,PHP在後端開發中更簡潔,但在前端開發中不如JavaScript。

PHP和Python各有優勢,適合不同場景。 1.PHP適用於web開發,提供內置web服務器和豐富函數庫。 2.Python適合數據科學和機器學習,語法簡潔且有強大標準庫。選擇時應根據項目需求決定。

PHP是一種廣泛應用於服務器端的腳本語言,特別適合web開發。 1.PHP可以嵌入HTML,處理HTTP請求和響應,支持多種數據庫。 2.PHP用於生成動態網頁內容,處理表單數據,訪問數據庫等,具有強大的社區支持和開源資源。 3.PHP是解釋型語言,執行過程包括詞法分析、語法分析、編譯和執行。 4.PHP可以與MySQL結合用於用戶註冊系統等高級應用。 5.調試PHP時,可使用error_reporting()和var_dump()等函數。 6.優化PHP代碼可通過緩存機制、優化數據庫查詢和使用內置函數。 7

PHP成為許多網站首選技術棧的原因包括其易用性、強大社區支持和廣泛應用。 1)易於學習和使用,適合初學者。 2)擁有龐大的開發者社區,資源豐富。 3)廣泛應用於WordPress、Drupal等平台。 4)與Web服務器緊密集成,簡化開發部署。

PHP在現代編程中仍然是一個強大且廣泛使用的工具,尤其在web開發領域。 1)PHP易用且與數據庫集成無縫,是許多開發者的首選。 2)它支持動態內容生成和麵向對象編程,適合快速創建和維護網站。 3)PHP的性能可以通過緩存和優化數據庫查詢來提升,其廣泛的社區和豐富生態系統使其在當今技術棧中仍具重要地位。

在PHP中,弱引用是通過WeakReference類實現的,不會阻止垃圾回收器回收對象。弱引用適用於緩存系統和事件監聽器等場景,需注意其不能保證對象存活,且垃圾回收可能延遲。

\_\_invoke方法允許對象像函數一樣被調用。 1.定義\_\_invoke方法使對象可被調用。 2.使用$obj(...)語法時,PHP會執行\_\_invoke方法。 3.適用於日誌記錄和計算器等場景,提高代碼靈活性和可讀性。


熱AI工具

Undresser.AI Undress
人工智慧驅動的應用程序,用於創建逼真的裸體照片

AI Clothes Remover
用於從照片中去除衣服的線上人工智慧工具。

Undress AI Tool
免費脫衣圖片

Clothoff.io
AI脫衣器

AI Hentai Generator
免費產生 AI 無盡。

熱門文章

熱工具

SublimeText3漢化版
中文版,非常好用

mPDF
mPDF是一個PHP庫,可以從UTF-8編碼的HTML產生PDF檔案。原作者Ian Back編寫mPDF以從他的網站上「即時」輸出PDF文件,並處理不同的語言。與原始腳本如HTML2FPDF相比,它的速度較慢,並且在使用Unicode字體時產生的檔案較大,但支援CSS樣式等,並進行了大量增強。支援幾乎所有語言,包括RTL(阿拉伯語和希伯來語)和CJK(中日韓)。支援嵌套的區塊級元素(如P、DIV),

DVWA
Damn Vulnerable Web App (DVWA) 是一個PHP/MySQL的Web應用程序,非常容易受到攻擊。它的主要目標是成為安全專業人員在合法環境中測試自己的技能和工具的輔助工具,幫助Web開發人員更好地理解保護網路應用程式的過程,並幫助教師/學生在課堂環境中教授/學習Web應用程式安全性。 DVWA的目標是透過簡單直接的介面練習一些最常見的Web漏洞,難度各不相同。請注意,該軟體中

Dreamweaver Mac版
視覺化網頁開發工具

SecLists
SecLists是最終安全測試人員的伙伴。它是一個包含各種類型清單的集合,這些清單在安全評估過程中經常使用,而且都在一個地方。 SecLists透過方便地提供安全測試人員可能需要的所有列表,幫助提高安全測試的效率和生產力。清單類型包括使用者名稱、密碼、URL、模糊測試有效載荷、敏感資料模式、Web shell等等。測試人員只需將此儲存庫拉到新的測試機上,他就可以存取所需的每種類型的清單。