Laravel 4.2  鑒權(quán)使用加鹽密碼

剛開始接觸laravel,發(fā)現(xiàn)laravel默認(rèn)的鑒權(quán)模塊密碼并未加鹽處理(密碼由password_hash方法創(chuàng)建)。所以自己琢磨著對(duì)密碼加鹽。像下面這樣校驗(yàn)密碼(密碼在最初創(chuàng)建時(shí),也以md5(salt . password .salt)的形式存儲(chǔ))

1 Auth::attempt(array('username'=>$user->username, 'password'=>$user->salt.Input::get('password').$user->salt))

但一直不成功,debug跟蹤源碼,可以看到最后,EloquentUserProvider的validateCredentials方法進(jìn)一步調(diào)用BcryptHasher的check方法,,再進(jìn)一步調(diào)用vendor/ircmaxell/password-compat/lib/password.php:230 password_verify方法,而不是我起初所想的直接$user->password == md5('input_password')。因此我在這里直接改寫了源碼,以此來實(shí)現(xiàn)密碼加鹽

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

Laravel 4.2  響應(yīng)存在多余的空行

在任意響應(yīng)中多四個(gè)空行,這個(gè)問題在4.2版本中遇到,并且在配置了auth過濾器的請(qǐng)求中才有

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

這個(gè)問題在下載請(qǐng)求時(shí)會(huì)有問題,比如壓縮文件。在下載zip文件時(shí),如果響應(yīng)前步多幾個(gè)空行,會(huì)造成文件起始多幾個(gè)字節(jié),造成這樣的錯(cuò)誤

warning [zip]: 8 extra bytes at beginning or within zipfile  。 因?yàn)榇a文件里是windows 換行符 CRLF,所以四個(gè)空行是八個(gè)字符,所以響應(yīng)頭部多了八個(gè)字節(jié)

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

或者提示 該文件已損壞或者需要另一個(gè)壓縮分卷

Laravel 5.3 清除客戶端cookie

有時(shí)需要服務(wù)端來清除cookie,以保證所有httponly屬性的cookie也能被清除。laravel已經(jīng)提供API來生成清除cookie的http頭

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

大學(xué)生就業(yè)培訓(xùn),高中生培訓(xùn),在職人員轉(zhuǎn)行培訓(xùn),企業(yè)團(tuán)訓(xùn)

Laravel 5.3 實(shí)現(xiàn)controller路由

laravel 5.3中移出了controller路由,只保留了resources路由,這對(duì)開發(fā)規(guī)范的項(xiàng)目而言是好事,而對(duì)開發(fā)不規(guī)范的項(xiàng)目簡(jiǎn)直是災(zāi)難,開發(fā)不得不用get或者post路由為每一個(gè)控制器的方法注冊(cè)路由,這會(huì)造成路由文件routes.php(routes/web.php)文件巨大不好維護(hù)。個(gè)人比較喜歡按約定來,所以寫了個(gè)函數(shù)簡(jiǎn)單實(shí)現(xiàn)controller路由(約定namespace/controller/method)格式,如Home/XxYyController@getMmGg 將映射到 url : home/xx-yy/mm-gg,并且是get請(qǐng)求

 1 /** 2  * 駝峰字符串轉(zhuǎn)蛇形字符串 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-gg21  * POST : XxYyController@postMmGg    ->  url :   h5/xx-yy/mm-gg22  * @param string $controller 控制器類名23  * @param bool $namespace  相對(duì)于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                 // 注冊(cè)get路由33                 $methodName = humpToSnake(lcfirst(substr($method,3)),'-');34                 Route::get($className.'/'.$methodName,$controller.'@'.$method);35             } else if(strpos($method,'post') === 0){36                 // 注冊(cè)post路由37                 $methodName = humpToSnake(lcfirst(substr($method,4)),'-');38                 Route::post($className.'/'.$methodName,$controller.'@'.$method);39             }40         }41     }42 }

在php項(xiàng)目中獨(dú)立使用Eloquent ORM框架

laravel使用的eloquent orm框架極其強(qiáng)大,大部分?jǐn)?shù)據(jù)庫層面的操作都能夠在不寫任何sql的情況下實(shí)現(xiàn)查詢。所以在寫其余項(xiàng)目時(shí),比如爬蟲,也想將此orm集成進(jìn)來

eloquent 是一個(gè)獨(dú)立的項(xiàng)目 https://github.com/illuminate/database,所以完全可以單獨(dú)拿出來用

通過composer在項(xiàng)目中安裝依賴

1 composer require illuminate/database:~4.2

將eloquent初始化的代碼獨(dú)立于一個(gè)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 /*創(chuàng)建連接*/30 $capsule->addConnection($database);31 /*設(shè)置全局訪問*/32 $capsule->setAsGlobal();33 /*啟動(dòng)Eloquent*/34 $capsule->bootEloquent();

定義數(shù)據(jù)庫模型 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 Eloquent10 {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 BaseModel10 {11     protected $table = 'apk_class';12 }

在需要進(jìn)行數(shù)據(jù)庫操作中引入初始化文件和模型文件即可以使用

 1 <?php 2 /** 3  * Created by PhpStorm. 4  * User: lvyahui 5  * Date: 2016/3/31 6  * Time: 17:00 7  * 掃描tmp/zip目錄,解壓左右的zip包,讓后進(jìn)行處理。 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 基于約定進(jìn)行子視圖填充

laravel 另一個(gè)強(qiáng)大之處是其模板引擎,開發(fā)中常用的有兩種,視圖繼承和子視圖填充。這里以子視圖填充為例,按約定的方式簡(jiǎn)化代碼的編寫

基礎(chǔ)控制器

  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方法會(huì)確定視圖文件位置。

<?phpclass 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     <!-- 頁面級(jí)別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 <!-- 頁面級(jí)別js文件 -->15 @yield('page.level.js','')16 <!-- 頁面級(jí)別js代碼片段 -->17 @yield('page.level.script','')18 </body>19 </html>

上面幾份代碼實(shí)現(xiàn)這樣的約定是:UserController@getList方法渲染views/user/list.blade.php頁面,并將其填充到view/layouts/site.blade.php視圖中,也就是我認(rèn)為整個(gè)站點(diǎn)主視圖(布局,layouts/site.blade.php)基本一致,所有方法產(chǎn)生的內(nèi)容直接填充主視圖即可,那以后開發(fā)新的頁面或者接口,只需要按改約定開發(fā)即可