最近项目中经常使用到了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: % Created project in test
Loading composer repositories with package information
Installing dependencies (including require-dev)
- Installing symfony/translation (v2.5.4)
Downloading: % - Installing psr/log (1.0.)
Downloading: % - Installing symfony/security-core (v2.5.4)
Downloading: % - Installing symfony/debug (v2.5.4)
Downloading: % - Installing symfony/http-foundation (v2.5.4)
Downloading: % - Installing symfony/event-dispatcher (v2.5.4)
Downloading: % - Installing symfony/http-kernel (v2.5.4)
Downloading: % - Installing symfony/routing (v2.5.4)
Downloading: % - Installing symfony/process (v2.5.4)
Downloading: % - Installing symfony/finder (v2.5.4)
Downloading: % - Installing symfony/console (v2.5.4)
Downloading: % - Installing symfony/filesystem (v2.5.4)
Downloading: % - Installing symfony/dom-crawler (v2.5.4)
Downloading: % - Installing symfony/css-selector (v2.5.4)
Downloading: % - Installing symfony/browser-kit (v2.5.4)
Downloading: % - Installing swiftmailer/swiftmailer (v5.2.2)
Downloading: % - Installing stack/builder (v1.0.2)
Downloading: % - Installing predis/predis (v0.8.7)
Downloading: % - Installing phpseclib/phpseclib (0.3.)
Downloading: % - Installing patchwork/utf8 (v1.1.25)
Downloading: % - Installing nesbot/carbon (1.13.)
Downloading: % - Installing monolog/monolog (1.10.)
Downloading: % - Installing nikic/php-parser (v0.9.5)
Downloading: % - Installing jeremeamia/superclosure (1.0.)
Downloading: % - Installing ircmaxell/password-compat (1.0.)
Downloading: % - Installing d11wtq/boris (v1.0.8)
Downloading: % - Installing classpreloader/classpreloader (1.0.)
Downloading: % - Installing filp/whoops (1.1.)
Downloading: % - Installing laravel/framework (v4.2.9)
Downloading: % 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..)
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
一共有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 = )
{
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中修改错误日志回调函数为:

// 错误日志信息
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', )
->where('teacher_id', )
->where('class_id', )
->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’=>, ’teacher_id’ => , ‘class_id’ => ])->get();

一下子腰也不酸了,头也不疼了。。。

后记

laravel还是能让一个phper学习到很多的,我努力着爱之深责之切的原则,后续使用laravel中使用不爽的地方再继续吐槽和讨论。

 
 

laravel吐槽系列之一的更多相关文章

  1. Laravel 5 系列入门教程(一)【最适合中国人的 Laravel 教程】

    Laravel 5 系列入门教程(一)[最适合中国人的 Laravel 教程] 分享⋅ johnlui⋅ 于 2年前 ⋅ 最后回复由 skys215于 11个月前 ⋅ 17543 阅读   原文发表在 ...

  2. Laravel 4 系列入门教程(一)

    默认条件 本文默认你已经有配置完善的PHP+MySQL运行环境,懂得PHP网站运行的基础知识.跟随本教程走完一遍,你将会得到一个基础的包含登录的简单blog系统,并将学会如何使用一些强大的Larave ...

  3. Laravel 5系列教程五:MVC的基本流程

    免费视频教程地址https://laravist.com/series/laravel-5-basic 期间受到很多私事影响,终于还是要好好写写laravel的教程了. 上一篇我们说了数据库和Eloq ...

  4. Laravel 5系列教程六:表单 Forms

    免费视频教程地址https://laravist.com/series/laravel-5-basic 在开始之前,我们把界面先美化一点点先: 首先到https://github.com/JellyB ...

  5. Laravel 5系列教程四:数据库和Eloquent

    免费视频教程地址https://laravist.com/series/laravel-5-basic 上一篇写了一些Laravel Blade的基本用法和给视图传递变量的几种方式, 这一节我们来说说 ...

  6. Laravel 5系列教程二:路由,视图,控制器工作流程

    免费视频教程地址https://laravist.com/series/laravel-5-basic 上一篇教程我们走了那么长的路,终于把Laravel安装好了,这一篇教程我们就要进入Laravel ...

  7. Laravel 5 系列教程三:视图变量传递和Blade

    免费视频教程地址https://laravist.com/series/laravel-5-basic 上一篇我们简单地说了Router,Views和Controllers的工作流程,这一次我就按照上 ...

  8. laravel进阶系列--通过事件和事件监听实现服务解耦

    简介 Laravel 事件提供了简单的观察着模式实现,允许你订阅和监听应用中的事件.事件类通常存放在 app/Events 目录. 监听器存放在 app/Listeners. 如果你在应用中没有看到这 ...

  9. techiediaries网站的Laravel 6系列教程

    Laravel 6 Tutorial & New Features - Build a CRM [PART 1] Laravel 6 REST API CRUD Tutorial - Buil ...

随机推荐

  1. Asp.Net MVC 扩展 Html.ImageFor 方法详解

    背景: 在Asp.net MVC中定义模型的时候,DataType有DataType.ImageUrl这个类型,但htmlhelper却无法输出一个img,当用脚手架自动生成一些form或表格的时候, ...

  2. 论checkbox和radio的样式美化问题

    如果你下定决心要改变现有的默认的checkbox和radio的样式,那么我目前有两种办法: 1.自己动手写一个,也就是自己写代码实现将input的checkbox和radio默认的样式隐藏掉,使用绝对 ...

  3. SQL关联查询总结

    employee表: department表: 笛卡儿积: 等值连接: 内连接(和等值连接效果是相同的): 外连接(外连接不仅返回满足条件的记录,还将返回不满足条件的记录)以下是左外连接,右外连接.全 ...

  4. 每天一个linux命令(61):wget命令

    Linux系统​中的wget是一个下载文件的工具,它用在命令行下.对于Linux用户是必不可少的工具,我们经常要下载一些软件或从远程服务器恢复备份到本地服务器.wget支持HTTP,HTTPS和FTP ...

  5. H5常用代码:适配方案4

    前面有分享了4种适配方案,但始终是通过手动缩放或者视口缩放来实现,用来做一些专题页,或者功能相对简单的项目来说也是完全能应付的,但整体来说感觉还是一种缩放,说不上是真正的适配,言外之意就是即将分享真正 ...

  6. [常见问题]Project facet Java versin 1.8 is not support.

    发生这个问题的原因是我们的java编译环境(JDK版本),与tomcat运行环境(JDK或JRE版本)不一致导致的. 到eclipse的设置中找到compile项(或右键项目进入),看一下编译环境的J ...

  7. js 的使用原则

    1.平稳退化:确保页面在没有javaScript的情况下也能正常运行 2.向后兼容:确保老版本的浏览器不会因为javaScript而死掉 3.性能最优:确保脚本执行的性能最优 4.页面与js分离:最大 ...

  8. 每天一个linux命令(16):which命令

    我们经常在linux要查找某个文件,但不知道放在哪里了,可以使用下面的一些命令来搜索:        which  查看可执行文件的位置.       whereis 查看文件的位置.         ...

  9. Mybatis中SqlMapper配置的扩展与应用(3)

    隔了两周,首先回顾一下,在Mybatis中的SqlMapper配置文件中引入的几个扩展机制: 1.引入SQL配置函数,简化配置.屏蔽DB底层差异性 2.引入自定义命名空间,允许自定义语句级元素.脚本级 ...

  10. 理解模板引擎Razor 的原理

    Razor是ASP.NET MVC 3中新加入的技术,以作为ASPX引擎的一个新的替代项.简洁的语法与.NET Framework 结合,广泛应用于ASP.NET MVC 项目.Razor Pad是一 ...