• Laravel 开发笔记


    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  相对于AppHttpControllers的命名空间
    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('AppHttpControllers\'.($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  IlluminateContainerContainer;
    25 use IlluminateDatabaseCapsuleManager 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 IlluminateDatabaseEloquentModel 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 IlluminateSupportFacadesView;
      4 use IlluminateSupportFacadesRedirect;
      5 use IlluminateSupportFacadesInput;
      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)基本一致,所有方法产生的内容直接填充主视图即可,那以后开发新的页面或者接口,只需要按改约定开发即可

  • 相关阅读:
    linux c 链接详解3-静态库
    ubuntu下安装chrome谷歌浏览器
    零填充(Zero-padding)
    单例模式的多种写法(线程安全)
    执行代码出现ImportError:attempted relative import with no known parent package
    用anaconda安装tensorflow
    A* 算法的原理
    梯度消失(vanishing gradient)和梯度爆炸(exploding gradient)
    spark安装
    [转]虚拟机VMware3种网络模式(桥接、nat、Host-only)的工作原理
  • 原文地址:https://www.cnblogs.com/lvyahui/p/6493095.html
Copyright © 2020-2023  润新知