laravel吐槽系列之一

最近項目中常用到了laravel框架,對於這個框架以前只是弱弱地接觸了一點,沒有深刻接觸,這下有時間好好研究它了(主要是不得不研究了)。說實話,laravel讓我打開眼界了,以前對框架的使用一直停留在yii1.X階段。總之那句話說的對,剛接觸laravel的phper就只有兩個反應,一個是撿到寶了,一個是以爲它是垃圾。我能,就屬於後者,因此如今在努力讓本身愛上laravel。可是一切老是有那麼硌人的地方,我就想寫寫一些東西來吐槽laravel。

吐槽點:laravel的vendor引用的組件過多 

laravel是遵循composer來寫的一個框架,問題是這個框架又引入了其餘的幾個組件,而後其餘的組件又引入了一些組件,反正下面是我composer create的時候須要引入的組件,本身看看吧。。。
➜  laravel  composer create-project laravel/laravel test --prefer-dist
Installing laravel/laravel (v4.2.0)
  - Installing laravel/laravel (v4.2.0)
    Downloading: 100%

Created project in test
Loading composer repositories with package information
Installing dependencies (including require-dev)
  - Installing symfony/translation (v2.5.4)
    Downloading: 100%

  - Installing psr/log (1.0.0)
    Downloading: 100%

  - Installing symfony/security-core (v2.5.4)
    Downloading: 100%

  - Installing symfony/debug (v2.5.4)
    Downloading: 100%

  - Installing symfony/http-foundation (v2.5.4)
    Downloading: 100%

  - Installing symfony/event-dispatcher (v2.5.4)
    Downloading: 100%

  - Installing symfony/http-kernel (v2.5.4)
    Downloading: 100%

  - Installing symfony/routing (v2.5.4)
    Downloading: 100%

  - Installing symfony/process (v2.5.4)
    Downloading: 100%

  - Installing symfony/finder (v2.5.4)
    Downloading: 100%

  - Installing symfony/console (v2.5.4)
    Downloading: 100%

  - Installing symfony/filesystem (v2.5.4)
    Downloading: 100%

  - Installing symfony/dom-crawler (v2.5.4)
    Downloading: 100%

  - Installing symfony/css-selector (v2.5.4)
    Downloading: 100%

  - Installing symfony/browser-kit (v2.5.4)
    Downloading: 100%

  - Installing swiftmailer/swiftmailer (v5.2.2)
    Downloading: 100%

  - Installing stack/builder (v1.0.2)
    Downloading: 100%

  - Installing predis/predis (v0.8.7)
    Downloading: 100%

  - Installing phpseclib/phpseclib (0.3.8)
    Downloading: 100%

  - Installing patchwork/utf8 (v1.1.25)
    Downloading: 100%

  - Installing nesbot/carbon (1.13.0)
    Downloading: 100%

  - Installing monolog/monolog (1.10.0)
    Downloading: 100%

  - Installing nikic/php-parser (v0.9.5)
    Downloading: 100%

  - Installing jeremeamia/superclosure (1.0.1)
    Downloading: 100%

  - Installing ircmaxell/password-compat (1.0.3)
    Downloading: 100%

  - Installing d11wtq/boris (v1.0.8)
    Downloading: 100%

  - Installing classpreloader/classpreloader (1.0.2)
    Downloading: 100%

  - Installing filp/whoops (1.1.2)
    Downloading: 100%

  - Installing laravel/framework (v4.2.9)
    Downloading: 100%

symfony/translation suggests installing symfony/config ()
symfony/translation suggests installing symfony/yaml ()
symfony/security-core suggests installing symfony/validator (For using the user password constraint)
symfony/security-core suggests installing symfony/expression-language (For using the expression voter)
symfony/event-dispatcher suggests installing symfony/dependency-injection ()
symfony/http-kernel suggests installing symfony/class-loader ()
symfony/http-kernel suggests installing symfony/config ()
symfony/http-kernel suggests installing symfony/dependency-injection ()
symfony/routing suggests installing symfony/config (For using the all-in-one router or any loader)
symfony/routing suggests installing symfony/yaml (For using the YAML loader)
symfony/routing suggests installing symfony/expression-language (For using expression matching)
symfony/routing suggests installing doctrine/annotations (For using the annotation loader)
predis/predis suggests installing ext-phpiredis (Allows faster serialization and deserialization of the Redis protocol)
phpseclib/phpseclib suggests installing ext-mcrypt (Install the Mcrypt extension in order to speed up a wide variety of cryptographic operations.)
phpseclib/phpseclib suggests installing ext-gmp (Install the GMP (GNU Multiple Precision) extension in order to speed up arbitrary precision integer arithmetic operations.)
phpseclib/phpseclib suggests installing pear-pear/PHP_Compat (Install PHP_Compat to get phpseclib working on PHP < 4.3.3.)
monolog/monolog suggests installing graylog2/gelf-php (Allow sending log messages to a GrayLog2 server)
monolog/monolog suggests installing raven/raven (Allow sending log messages to a Sentry server)
monolog/monolog suggests installing doctrine/couchdb (Allow sending log messages to a CouchDB server)
monolog/monolog suggests installing ruflin/elastica (Allow sending log messages to an Elastic Search server)
monolog/monolog suggests installing ext-amqp (Allow sending log messages to an AMQP server (1.0+ required))
monolog/monolog suggests installing ext-mongo (Allow sending log messages to a MongoDB server)
monolog/monolog suggests installing aws/aws-sdk-php (Allow sending log messages to AWS services like DynamoDB)
monolog/monolog suggests installing rollbar/rollbar (Allow sending log messages to Rollbar)
laravel/framework suggests installing doctrine/dbal (Allow renaming columns and dropping SQLite columns.)
Writing lock file
Generating autoload files
Mcrypt PHP extension required.
Script php artisan clear-compiled handling the post-install-cmd event returned with an error
View Code

 

一共有28個須要Install的,這個致使的結果是初始化可運行的項目大小有25M之大。
這麼bigger than bigger的玩意,首先會帶來部署上的不便利。
部署laravel項目的時候會有兩種方式,一種是隻發佈除了vendor以外的項目相關的文件,而後運行composer進行vender的更新,另一種是直接將vendor進入版本庫,使用版本庫的發佈將全部代碼發佈到線上機器去。我我的傾向第二種,能把代碼庫中的文件直接放到服務器上就能運行的多牛逼。可是這樣子,代碼庫就變得超大了,不大便利了。
 
其次,這麼多的vendor致使的是文檔查閱的不方便。
一個框架好用很差用,文檔是一個相當重要的環節。可是引用的第三方庫一多了,不少使用文檔官方就沒有足夠詳細的文檔說明了,而後美其名告訴你,這個是引用第三方庫的,給你個連接,你去第三方庫的說明文檔中看把。可是你要知道,在開發過程當中,文檔是須要有統一性的,每個說明文檔的展現和查詢規則都是有慣性的。你給個連接讓我去一個不同佈局的網頁,個人思惟還須要進行跳躍和查找。

解決辦法:忍 

吐槽點:laravel的路由能夠寫function

laravel的路由很是強大,強大到無敵了。好比說呢,什麼controller,action啥的都是浮雲,哥能夠在app/route.php裏面直接寫上路由對應的funciton,啥controller都不用寫了,一個文件能夠do everything。可是,什麼都能作的框架就是把規則的制定推給使用者。好比在route中能夠容許寫function,我第一次看到的時候以爲渾身都不對了,一個制定路由的文件,你就制定哪一個路由到哪一個action就好,幹毛在一個叫route.php的文件裏面,制定具體的執行方法。我估摸不少團隊都會約定不容許在route裏面寫funciton,由於這樣就個路由的設置就很雞肋了。

解決辦法:團隊自行作一些規定來限制路由的功能。

吐槽點:laravel沒有默認路由 

我這裏說的是好比yii中有默認路由的方式controller/action。好比user/index 默認就對應到userController 的IndexAction中去。可是在laravel中,它將這種名稱依賴的默認路由去掉了。全部laravel中使用的路由都須要手動在route.php中制定諸如這樣的命令:
Route::get('login', ['as' => 'login', 'uses' => 'UserController@login']);
可是特別在作後臺開發的時候真是特別沒法忍受,每次增長一個路由都須要在route中加入這麼一條玩意。
 
最後我取折衷的辦法,在後臺開發的時候,多使用這樣的語句:
Route::controller('series', 'SeriesController’);
這樣,在controller中定義的getXXX和postXXX就能自動解析了,就不須要那麼繁雜的寫route路徑了。 

解決辦法:多使用Route::controller 

吐槽點:日誌記錄信息太多了

看看默認的laravel.log中的一個錯誤:
 
我能罵髒話麼,laravel中因爲使用了大量的組件,致使laravel的堆棧很是長,而後呢,錯誤日誌中就把堆棧打印出來了,汗,上面那麼多的錯誤信息,居然沒有記錄當前的請求URL和請求參數。看着這麼多錯誤信息的日誌,我居然無言以對,我應該看哪裏,去哪裏找出這個錯誤呢?
 
對於日誌存儲,laravel使用monlog,雖說是很強大了,可是它還有個問題,就是若是你想要讓日誌記錄到不一樣日誌文件實現起來比較複雜。首先你可能會想到使用useFiles或者useDailyFiles來記錄到不一樣的文件,可是Log是Facade模式的,一旦修改了useFile,你就要修改回來才行。其次,你可能會想到使用這個文章中的方法:
http://laravel.io/forum/02-09-2014-laraverl-custom-logs,new一個,再Info,好吧,實際後來我也是用相似的方法封裝了下。最後,你的方法可能就是寫個log的ServiceProvider,覆蓋或者重寫原先的哪一個Log。
 
總之達成目的的方法必定不止一個,but,總之,原先的哪一個Log仍是不爽。 

解決方法:自定義日誌編輯類

首先自定義了日誌編輯類:
<?php
namespace Yejiafneng\Helpers;
 
use Monolog\Logger;
use Monolog\Handler\StreamHandler;
use Illuminate\Log\Writer;
 
class BLogger
{
    // 全部的LOG都要求在這裏註冊
    const LOG_ERROR = 'error';
    const LOG_SHOP = 'shop';
    const LOG_QUERY = 'query';
    const LOG_LOGIN = 'login';
 
    private static $loggers = array();
 
    // 獲取一個實例
    public static function getLogger($type = self::LOG_ERROR, $day = 30)
    {
        if (empty(self::$loggers[$type])) {
            self::$loggers[$type] = new Writer(new Logger($type));
        }
        $log = self::$loggers[$type];
        $log->useDailyFiles(storage_path().'/logs/'. $type .'.log', $day);
        return $log;
    }
}

 而後在app/start/global.php中修改錯誤日誌回調函數爲:php

// 錯誤日誌信息
App::error(function(Exception $exception, $code)
{
    // 若是沒有路徑就直接跳轉到登陸頁面
    if ($exception instanceof NotFoundHttpException) {
        return Redirect::route('login');
    }
 
     Log::error($exception);
 
    $err = [
        'message' => $exception->getMessage(),
        'file' => $exception->getFile(),
        'line' => $exception->getLine(),
        'code' => $exception->getCode(),
        'url' => Request::url(),
        'input' => Input::all(),
    ];
    BLogger::getLogger(BLogger::LOG_ERROR)->error($err);
});

 

這裏沒有修改laravel自身的錯誤日誌記錄,由於保留一個全集的錯誤應該仍是有必要的,可是實際上我使用過程當中只要看本身定義的error.log就足夠了
 
 
 

吐槽點:ORM的where太弱 

laravel的ORM使用的是Eloquent ORM。若是你要獲取出Student表中female=1 而且 teacher_id爲4 而且class_id爲3的全部學生,你須要這麼寫:
Student::where('female', 1)
->where('teacher_id', 4)
->where('class_id', 3)
->get();
好難受,若是一個還行,要是多個呢?。。。難道就不能在一個where中使用個數組麼?

解決辦法:在基類中擴展一個multiwhere 

因而我就在BaseModel中定義了:
    // 多where
    public function scopeMultiwhere($query, $arr)
    {
        if (!is_array($arr)) {
            return $query;
        }
 
        foreach ($arr as $key => $value) {
            $query = $query->where($key, $value);
        }
        return $query;
    }

 

這樣子,上面的語句就能夠這麼使用:
Student::multiwhere([‘female’=>1, ’teacher_id’ => 4, ‘class_id’ => 3])->get();

 一會兒腰也不酸了,頭也不疼了。。。css

後記

laravel仍是能讓一個phper學習到不少的,我努力着愛之深責之切的原則,後續使用laravel中使用不爽的地方再繼續吐槽和討論。laravel

相關文章
相關標籤/搜索