Laravel 4.2 鑒權使用加鹽密碼
剛開始接觸laravel,發現laravel預設的鑒權子產品密碼并未加鹽處理(密碼由password_hash方法建立)。是以自己琢磨着對密碼加鹽。像下面這樣校驗密碼(密碼在最初建立時,也以md5(salt . password .salt)的形式存儲)
1 Auth::attempt(array('username'=>$user->username, 'password'=>$user->salt.Input::get('password').$user->salt))
但一直不成功,debug跟蹤源碼,可以看到最後,EloquentUserProvider的validateCredentials方法進一步調用BcryptHasher的check方法,,再進一步調用vendor/ircmaxell/password-compat/lib/password.php:230 password_verify方法,而不是我起初所想的直接$user->password == md5('input_password')。是以我在這裡直接改寫了源碼,以此來實作密碼加鹽
Laravel 4.2 響應存在多餘的空行
在任意響應中多四個空行,這個問題在4.2版本中遇到,并且在配置了auth過濾器的請求中才有
這個問題在下載下傳請求時會有問題,比如壓縮檔案。在下載下傳zip檔案時,如果響應前步多幾個空行,會造成檔案起始多幾個位元組,造成這樣的錯誤
warning [zip]: 8 extra bytes at beginning or within zipfile 。 因為代碼檔案裡是windows 換行符 CRLF,是以四個空行是八個字元,是以響應頭部多了八個位元組
或者提示 該檔案已損壞或者需要另一個壓縮分卷
Laravel 5.3 清除用戶端cookie
有時需要服務端來清除cookie,以保證所有httponly屬性的cookie也能被清除。laravel已經提供API來生成清除cookie的http頭
Laravel 5.3 實作controller路由
laravel 5.3中移出了controller路由,隻保留了resources路由,這對開發規範的項目而言是好事,而對開發不規範的項目簡直是災難,開發不得不用get或者post路由為每一個控制器的方法注冊路由,這會造成路由檔案routes.php(routes/web.php)檔案巨大不好維護。個人比較喜歡按約定來,是以寫了個函數簡單實作controller路由(約定namespace/controller/method)格式,如Home/XxYyController@getMmGg 将映射到 url : home/xx-yy/mm-gg,并且是get請求
1 /**
2 * 駝峰字元串轉蛇形字元串
3 * @param $str
4 * @param string $delimiter
5 * @return string
6 */
7 function humpToSnake($str,$delimiter = '_'){
8 if ( ! ctype_lower($str))
9 {
10 $replace = '$1'.$delimiter.'$2';
11 $str = strtolower(preg_replace('/([A-Za-z])([A-Z])/', $replace, $str));
12 }
13 return $str;
14 }
15
16
17 /**
18 * 基于controller約定路由
19 * 例如: $namespace = 'H5'
20 * GET : XxYyController@getMmGg -> url : h5/xx-yy/mm-gg
21 * POST : XxYyController@postMmGg -> url : h5/xx-yy/mm-gg
22 * @param string $controller 控制器類名
23 * @param bool $namespace 相對于App\Http\Controllers的命名空間
24 */
25 function routeController($controller,$namespace = false){
26 if (preg_match('/([\w]+)Controller$/', $controller, $matches))
27 {
28 $className = humpToSnake($matches[1],'-');
29 $methods = get_class_methods('App\Http\Controllers\\'.($namespace ? $namespace.'\\' : '').$controller);
30 foreach($methods as $method){
31 if(strpos($method,'get') === 0){
32 // 注冊get路由
33 $methodName = humpToSnake(lcfirst(substr($method,3)),'-');
34 Route::get($className.'/'.$methodName,$controller.'@'.$method);
35 } else if(strpos($method,'post') === 0){
36 // 注冊post路由
37 $methodName = humpToSnake(lcfirst(substr($method,4)),'-');
38 Route::post($className.'/'.$methodName,$controller.'@'.$method);
39 }
40 }
41 }
42 }
在php項目中獨立使用Eloquent ORM架構
laravel使用的eloquent orm架構極其強大,大部分資料庫層面的操作都能夠在不寫任何sql的情況下實作查詢。是以在寫其餘項目時,比如爬蟲,也想将此orm內建進來
eloquent 是一個獨立的項目 https://github.com/illuminate/database,是以完全可以單獨拿出來用
通過composer在項目中安裝依賴
1 composer require illuminate/database:~4.2
将eloquent初始化的代碼獨立于一個php檔案(start.php)中
1 <?php
2 /**
3 * Created by PhpStorm.
4 * User: lvyahui
5 * Date: 2016/3/17
6 * Time: 17:23
7 */
8 require_once __DIR__ . '/vendor/autoload.php';
9 require_once 'config.php';
10
11 $localDBConf = config('db.local');
12
13 $database = array(
14 'driver' => 'mysql',
15 'host' => $localDBConf['host'],
16 'port' => $localDBConf['port'],
17 'database' => $localDBConf['name'],
18 'username' => $localDBConf['user'],
19 'password' => $localDBConf['pass'],
20 'charset' => 'utf8',
21 'collation' => 'utf8_unicode_ci',
22 );
23
24 //use Illuminate\Container\Container;
25 use Illuminate\Database\Capsule\Manager as Capsule;
26
27 $capsule = new Capsule();
28
29 /*建立連接配接*/
30 $capsule->addConnection($database);
31 /*設定全局通路*/
32 $capsule->setAsGlobal();
33 /*啟動Eloquent*/
34 $capsule->bootEloquent();
定義資料庫模型 BaseModel.php
1 <?php
2 use Illuminate\Database\Eloquent\Model as Eloquent;
3 /**
4 * Created by PhpStorm.
5 * User: samlv
6 * Date: 2016/3/17
7 * Time: 17:30
8 */
9 class BaseModel extends Eloquent
10 {
11 protected $guarded = array('id');
12 public $timestamps = false;
13 }
ApkClass.php
1 <?php
2 require_once ('BaseModel.php');
3 /**
4 * Created by PhpStorm.
5 * User: lvyahui
6 * Date: 2016/3/31
7 * Time: 16:35
8 */
9 class ApkClass extends BaseModel
10 {
11 protected $table = 'apk_class';
12 }
在需要進行資料庫操作中引入初始化檔案和模型檔案即可以使用
1 <?php
2 /**
3 * Created by PhpStorm.
4 * User: lvyahui
5 * Date: 2016/3/31
6 * Time: 17:00
7 * 掃描tmp/zip目錄,解壓左右的zip包,讓後進行處理。
8 */
9 require_once ('start.php');
10 require_once ('models/ApkClass.php');
11
12 foreach($usedApkClasss as $map_id=>$num){
13 ApkClass::where('map_id',$map_id)->update(array('num' => $num));
14 }
Laravel 基于約定進行子視圖填充
laravel 另一個強大之處是其模闆引擎,開發中常用的有兩種,視圖繼承和子視圖填充。這裡以子視圖填充為例,按約定的方式簡化代碼的編寫
基礎控制器
1 <?php
2
3 use Illuminate\Support\Facades\View;
4 use Illuminate\Support\Facades\Redirect;
5 use Illuminate\Support\Facades\Input;
6 class BaseController extends Controller
7 {
8
9 protected $layout = 'layouts.site';
10
11 protected $stdName = null;
12
13 protected $routeParams = false;
14 /**
15 * Setup the layout used by the controller.
16 *
17 * @return void
18 */
19 protected function setupLayout()
20 {
21 if ( ! is_null($this->layout))
22 {
23 $this->layout = View::make($this->layout);
24 }
25 }
26
27 public function __construct()
28 {
29
30 }
31
32 /**
33 * 擷取控制器名稱
34 * 例如:
35 * 類:admin/DataSourceController
36 * 将傳回
37 * dataSource
38 * @return null|string
39 */
40 public function getStdName()
41 {
42 if(!$this->stdName){
43 $className = get_class($this);
44 if (preg_match('/([\w]+)Controller$/', $className, $matches))
45 {
46 // $this->stdName = camel_case($matches[1]);
47 $this->stdName = lcfirst($matches[1]);
48 }
49 else
50 {
51 $this->stdName = $className;
52 }
53 }
54 return $this->stdName;
55 }
56
57
58 public function makeView($data = array(),$view = null){
59 if(!$view){
60 $routeParams = $this->getRouteParams();
61 $controllerName = $routeParams['c'];
62 $methodName = $routeParams['m'];
63 if(preg_match('/^get(.*)$/',$methodName,$matches)){
64 $methodName = StringUtils::humpToSnake($matches[1]);
65 }
66 $view = $controllerName.'.'.$methodName;
67 }
68 if(!is_array($data)){
69 $data = array();
70 }
71 if(Request::ajax()){
72 return View::make($view,$data);
73 }else{
74 $this->layout->nest('content',$view,$data);
75 return false;
76 }
77 }
78
79 /**
80 *
81 * @return array|bool
82 */
83 public function getRouteParams(){
84 if(!$this->routeParams){
85
86 list($class,$method) = explode('@',Route::current()->getActionName());
87 $class = str_replace("\\",".",substr($class,0,strrpos($class,'Controller')));
88 // $names = explode(".",$class);
89 // foreach ($names as & $name) {
90 // $name = snake_case($name);
91 // }
92 $class = StringUtils::humpToSnake($class);
93 // $class = implode('.',$names);
94
95 $this->routeParams = array(
96 'c' => $class,
97 'm' => $method
98 );
99 }
100
101 return $this->routeParams;
102 }
103
104 public function getRouteParam($key){
105 $routePatams = $this->getRouteParams();
106 return $routePatams[$key];
107 }
108
109 }
控制器方法中隻需要return makeView()方法即可,makeView方法會确定視圖檔案位置。
<?php
class UserController extends BaseController
{
public function getList(){
return $this->makeView(array('users'=>array()));
}
}
主視圖(site.blade.php)寫法
1 <!DOCTYPE html>
2 <html lang="zh-CN">
3 <head>
4 @include('layouts.head')
5 <!-- 頁面級别css -->
6 @yield('page.level.css','')
7 </head>
8 <body>
9 @include('layouts.header')
10 <div class="container-fluid">
11 {{$content}}
12 </div>
13 @include('layouts.footer')
14 <!-- 頁面級别js檔案 -->
15 @yield('page.level.js','')
16 <!-- 頁面級别js代碼片段 -->
17 @yield('page.level.script','')
18 </body>
19 </html>
上面幾份代碼實作這樣的約定是:UserController@getList方法渲染views/user/list.blade.php頁面,并将其填充到view/layouts/site.blade.php視圖中,也就是我認為整個站點主視圖(布局,layouts/site.blade.php)基本一緻,所有方法産生的内容直接填充主視圖即可,那以後開發新的頁面或者接口,隻需要按改約定開發即可