我自己學習 PHP 其實都只是一年前開始,這是因為我選修了兩科關於 PHP 的科目。那時學的都是一些最基本的 PHP,製作 HTML 表單連驗證、修改、儲存到資料庫都是用同一個 PHP 檔案,內裏用幾個 if
來分隔開不同的部分,還會用 session 來重新填寫表單內容。現在回想起都覺得這種寫法非常嘔心,因為實在太長,而且夾雜着 PHP 和 HTML,自己寫完都不想再去看。
所以那時就試用 CodeIgniter 這套 PHP framework 來做 project,因為這些 Framework 都會替你分好 MVC,不用自己慢慢研究怎樣分,只要跟着它的習慣去寫就不會再有一個 PHP 檔做全部的動作。 過了幾個月之後,在 Nettuts+ 看到有關 Laravel 的介紹,覺得它不錯。它提供的 function 就算不看說明文件也可以大約估計到它的意思,而且說明文件簡單明瞭,大部分要用到的功能都會在說明文件中找到,不用查 API。據介紹 Laravel 是抄 Ruby on Rails 的特色,例如有:
- ActiveRecord:即是 Laravel 叫的 Eloquent ORM (Object Relational Mapping),可以用簡單易明的語法來做 database CRUD,無需寫 SQL statement
- Migration:將 Database schema 的改動寫入 PHP 檔內,再用 Laravel 提供的 Artisan CLI 工具執行或者還原到上一個版本。方便和其他開發人員同步各自 database 的 schema,不用再 export SQL file
- Generate:透過 Laravel 4 的 Artisan CLI 工具產生 PHP 檔案(例如 Controller class、Model class、View 等等,Laravel 3 可以裝第三方的 command 來補上這個功能)
- Gems:Laravel 3 是用自家制式的 Bundle;Laravel 4 是用 Composer
- RESTful:可以做到 RESTful controller,Laravel 4 還新加了 Resource controller 再加上一堆常用的現成功能如 HTML 表單製作 helper class、表單驗証、登入系統、Blade template(Laravel 自家 Templating 格式)、Pagination、Routing 等等令開發時間加快。上月開站的 CityU GE 指南都是用 Laravel 3 寫的,再配 Twitter Bootstrap、Font Awesome 做 UI。
而 Laravel 4 (L4) 在上星期推出了 4.0.0 版,這個版本基本上是重新寫過。亦正因為它是重新寫過,大部分 Laravel 3 (L3) 的 Class 和 Function 都改了,如果要升級的話就要逐個 PHP 檔案改成 L4 的 Class 和 Function。除了加添更多新功能外,L4 最大的改變是轉用 Composer 來管理組件,整個 Framework 都是由不同的組件組合而成。如果不喜歡 Laravel 的作法可以裝原裝組件換成自己喜歡的,例如將 Blade 換做 Smarty。而 L4 本身亦用上了其他現成的組件,例如 Symfony、whoops!(L4 那個很漂亮的錯誤報告畫面就是用這個 Library 做出來的)、Swift Mailer 等等。組件的安裝和更新可以用 Composer 替你完成,不用再自己手動換檔案。另一樣比較明顯的變化是 L4 遵守 PSR-0 and PSR-1 標準,Class 名要用 StudlyCaps、Function 名要用 camelCase,和新的 PHP 5 class 或者 Java 一樣。幸好 CityU GE 指南的規模不大,三兩日就可以將原先的 code 升級成 L4。首先要大改的就是將原先的 snake_case variable / function / class 名按照 PSR-1 標準替換。其次是將 class / function 名變成 L4 的(因為有不少常用的 function 都改了 signature)。之後再到 Packagist 找尋 reCAPTCHA、RSS feed 和 Sitemap class 的組件取代原先的 L3 bundle,並用 Composer 加到 project 內。這個過程都算輕鬆,因為這些組件是一般常用的組件,很容易找到。
Laravel 3 和 Laravel 4 的用法上的改動可以參考 Jeffery Way 的 Laravel 4 Mastery 和 Jason Lewis 的 Laravel 4: Illuminating Your Laravel 3 Applications。不過因為這些影片和文章都是在 Beta 版時寫的,和正式版會有小量出入。以下是我升級 CityU GE 指南時主要遇到的變化:
HTML、Form、Blade、Asset Management、i18n
- L3 用來產生 HTML
<a>
tag 的HTML::link()
、HTML::link_to_route()
、HTML::link_to_secure()
在 L4 變成了 global functionlink_to()
、link_to_action()
Form
class 仍然存在,在 L4 beta 時曾傳出 L4 會取消Form::open()
的傳入參數改為一個 associative arrayAsset
class 已經消失,要自己找替代品,或者乾脆不用- Blade 的
@include()
易名為@extends()
- Blade 的
@endsection
易名為@stop
(但不轉也可以用到,但上面的@include
就一定要改) - Blade 新增了
{{{ }}}
語法,括在裏面的 variable 會做一次 HTML escape;而原有的{{ }}
語法就和以前一樣不會 escape e()
這個 escape HTML entity 的 function 仍然存在Lang
class 已經可以支援單數 / 眾數 / 個別數量時會套用不同款的翻譯字串- L3 內
__()
這個模仿 gettext 的 functoin 在 L4 改為trans()
和trans_choice()
或者Lang::get()
和Lang::choice()
Pagination
- Paginate 過的 variable 如果要取得本頁的行列的話 L3 是
foreach ($courses->results as $course) {...}
;L4 則不用再加results
,即是foreach ($courses as $course) {...}
- 因為上述的改動,如果要檢查 paginate 過的結果是否為空的話,要使用
if (!$courses->getTotal()) {...}
Route
- 新增了 resource controller:
Route::resource()
(可以方便做 RESTful API,它會自動產生 RESTful URL,並且會有 route name) - 新增了 sub-domain routing
- 新增了 route prefix(即是網址中段的 directory 名),例如要做一個 admin section,不用再每個 admin section 的 route 加
/admin/
,可以用Route::group(array('prefix' => 'admin'), function() {...})
包起所有 admin section 的 route
URL、Request、Response
URL::base()
這個 function 改為使用URL::to('')
- L3 要取得目前這個 request 的 route name 是用
Request::route()->action['as']
而 L4 是用Route::currentRouteName()
- 要送出 HTTP 404、500 等 error,L3 是用
return Response::error('404')
而 L4 是用return App::abort(404)
Raw Query、Eloquent、Migration
- L3 raw query 的
DB::only()
在 L4 已經取消 - L4 可以用到 transaction
- L3 要執行 raw query 是
DB::query()
而 L4 則分拆成DB::select()
、DB::insert()
、DB::update()
、DB::delete()
和DB::statement
- Eloquent model 的 getter 和 setter function 的命名規則分別改為
getFooAttribute()
和setFirstNameAttribute()
,Foo
和FirstName
是 database column 名(留意 column 名仍然是用 snake_case,所以setFirstNameAttribute()
是對應 database table 的first_name
column) - 新加了 database seed 功能,可以不用再將填測試或預設資料寫成 DB schema 的 migration,並且在有需要時才導入到資料庫中
- 經 Eloquent 取得的
created_at
、updated_at
和deleted_at
column 不再是普通的 string,而是 extends 自DateTime
的 Carbon object,它提供一些方便易用的 function 來切換顯示格式、運算和處理這些日期和時間
Artisan
- 新增了
php artisan serve
,只要讓 console 開着的話就可以用 PHP 內置的網頁伺服器運行這個 Laravel project,可以不用設定 VirtualHost - 新增了
php artisan controller:make
,用來產生 resource controller - 新增了
php artisan optimize
,用來產生最佳化過的 class loader,加快載入速度 - 新增了
php artisan migrate:refresh
,可以還原所有 migration 並重新執行所有 migration
其他
dd()
仍然可以使用- L4 目前未有內置 profiler bar (Anbu),但可以用 loic-sharma/profiler 代替 其實還有很多的改變,只是我在這次升級未有遇到。要查 L4 的說明文件可以到 Laravel 官方網站,官方網站亦都有 L4 API。說明文件並沒有將所有 function 列出,如果要找一些比較少用的 function 就要到 API documentation 查。如果已經有 L3 的 project 的話,其實可以繼續用 L3。因為升級不只是換 Laravel 的核心檔案,還要逐個檔案去改。但如果是要開始一個新 project 的話,就最好用 L4。因為 L3 將會淡出,日後未必再有新的 L3 bundle 可以用。相反,L4 是用 Packagist,愈來愈多 PHP framework 都開始支援 Packagist / Composer,這意味着日後會有更多現成組件可以用,節省自己開發的時間。