Laravel开发采坑系列问题
2017年12月22日17:40:03 不定时更新
版本5.4.X
一下是可能会遇到的坑
1,必须的写路由转发才能访问控制器,当然你可以自动路由访问,但是需要些匹配规则,其实还是转发了
好多人讨论过自动路由的缺点,但是中小项目用不上,而且暴露在外的接口,现在大多数都是有路由转发,完全可以通过分组来兼容多种开发习惯和需求,并不是自动路由就狗屁不是
2,Laravel 做计划任务的时候坑真的好多,比如不能直接跨控制器访问,web的是web的路由,console是它自己的,所以你的功能和逻辑代码必须在Repository或者service里面,不然你懂的,做好逻辑代码分离
官方文档只有用过的才能看得懂,我很无奈
完整流程
app\Console\Commands下建立你的任务文件
- SpiderTask.php
- <?php
- namespace App\Console\Commands;
- use Illuminate\Console\Command;
- //use Illuminate\Support\Facades\Redis;
- use App\Repositories\SpiderRepository;//具体逻辑代码
- class SpiderTask extends Command {
- protected $taskserver;
- /**
- * The name and signature of the console command.
- *
- * @var string
- */
- protected $signature = 'SpiderTask';
- /**
- * The console command description.
- *
- * @var string
- */
- protected $description = 'spider every one hour crawl data';
- protected $spider;
- /**
- * Create a new command instance.
- *
- * @return void
- */
- public function __construct() {
- parent::__construct();
- $this->spider = new SpiderRepository();
- }
- /**
- * Execute the console command.
- *
- * @return mixed
- */
- public function handle() {
- $this->spider->do_all();//具体执行地方
- }
- }
然后注册到Kernel.php
- <?php
- namespace App\Console;
- use Illuminate\Console\Scheduling\Schedule;
- use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
- use App\Repositories\SpiderRepository;//我的具体逻辑代码地方
- class Kernel extends ConsoleKernel {
- /**
- * The Artisan commands provided by your application.
- *
- * @var array
- */
- protected $commands = [
- //
- 'App\Console\Commands\SpiderTask', //必须
- ];
- /**
- * Define the application's command schedule.
- *
- * @param \Illuminate\Console\Scheduling\Schedule $schedule
- * @return void
- */
- protected function schedule(Schedule $schedule) {
- // $schedule->call(function () {
- // $Spider = new SpiderRepository();
- // $Spider->do_all();
- // })->daily();
- $schedule->command('SpiderTask')->daily();
//两种方法都可以,建议第二种,逻辑更清晰- }
- /**
- * Register the Closure based commands for the application.
- *
- * @return void
- */
- protected function commands() {
- require base_path('routes/console.php');
- }
- }
注意:
你要测试你的代码逻辑有没有错误
最好在Linux下测试,因为windows好多问题
在代码根目录,如果命令没有到全局,使用完整路径
- php artisan schedule:run
everyMinute才会实时运行,可以看到报错
- $schedule->command('SpiderTask')->everyMinute();
http://laravelacademy.org/post/6931.html 官方文档
- <?php
- namespace App\Repositories;
- use App\Models\Spider;
- //use phpspider\core\phpspider;
- use phpspider\core\requests;
- use phpspider\core\selector;
- class SpiderRepository {
- use BaseRepository;
- protected $model;
- /**
- * ActivityRepository constructor.
- * @param Activity $activity
- */
- public function __construct() {
- $this->model = new Spider();
- }
- public function do_all() {
- $this->cjysjs();
- $this->shysjs();
- $this->nchn();
- $this->ltbj();
- }
- //长江有色金属
- public function cjysjs() {
- $html = requests::get('http://www.ccmn.cn/');
- $data = selector::select($html, "#40288092327140f601327141c0560001", "css");
- $data1 = selector::select($data, "tr", "css");
- array_shift($data1);
- $array = array();
- if (!empty($data1) && is_array($data1)) {
- foreach ($data1 as $k => &$v) {
- $data2 = selector::select($v, "td", "css");
- foreach ($data2 as $kk => &$vv) {
- $vv = str_replace('
- ', '', $vv);
- $vv = str_replace(array("\r\n", "\r", "\n"), "", $vv);
- $vv = trim($vv);
- }
- $data2['3'] = selector::select($data2['3'], "font", "css");
- unset($data2['6']);
- $array[] = $data2;
- }
- if (empty($array)) {
- $info = date("Y-m-d H:i:s", time()) . ':长江有色金属抓取失败!';
- Log::info($info);
- }
- $name = 'cjysjs';
- $_data = [];
- if (!empty($array) && is_array($array)) {
- $_data['value'] = json_encode($array);
- $_data['crawl_time'] = time();
- $count = $this->getData($name);
- if (empty($count)) {
- //增加
- $_data['name'] = $name;
- $result = $this->saveData(null, $_data);
- } else {
- //更新
- $_data['name'] = $name;
- $result = $this->saveData($name, $_data);
- }
- }
- }
- }
- public function saveData($name = null, $data = null) {
- return $this->model->updateOrCreate(['name' => $name], $data);
- }
- public function getData($name) {
- return $this->model->where('name', $name)->count();
- }
- }
添加计划任务
- * * * * * php /path/to/artisan schedule:run >> /dev/null 2>&1
- /dev/null 2>&1 必须,其实为了把错误信息和输出输出到/dev/null 文件
注意php是否是全局,不是就全路径,artisan网站根目录- 获取错误
- Laravel 调度器为处理调度任务输出提供了多个方便的方法。首先,使用sendOutputTo 方法,你可以发送输出到文件以便稍后检查:
- $schedule->command('emails:send')
- ->daily()
- ->sendOutputTo($filePath);
- 如果你想要追加输出到给定文件,可以使用 appendOutputTo 方法:
- $schedule->command('emails:send')
- ->daily()
- ->appendOutputTo($filePath);
- 使用 emailOutputTo 方法,你可以将输出发送到电子邮件。使用电子邮件发送任务输出之前,需要配置 Laravel 的电子邮件服务:
- $schedule->command('foo')
- ->daily()
- ->sendOutputTo($filePath)
- ->emailOutputTo('foo@example.com');
3,laravel增加第三类或者库文件
lavavel是封装的比较好的框架,那么composer,要么遵循他的规范,我在使用tcpdf在laravel5.4的时候,发现一个问题
laravel的某种组件要php7以上版本,服务器上又只有5.6我又不想麻烦,想直接引入tcpdf,发现完全不行,la回去直接通过空间路径去引入文件读取,
这样一来,就不能直接引入,解决方案不难,也不用升级php版本,
- composer.json
- "autoload": {
- "classmap": [
- "database",
- "app/Libarary/tcpdf"
- ],
- "psr-4": {
- "App\\": "app/"
- },
- "files": [
- "app/Tools.php",
- "app/WeiXin.php"
- ]
- },
我引入tcpdf在app下面的/Libarary/tcpdf
然后
composer dumpautoload
注意,如果你本地composer比较麻烦,你可以在虚拟机上执行,在吧代码拉回来,因为windows上实在难用
代码使用比较简单
- use TCPDF;
- public function index() {
- $pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
- }
就OK了
4,在某些特殊环境下模型的 create方法,会把很大的数字 2018011900012 转换成 -622729113的负数,数据库存的string varchar,底层原因未知
解决方法,如果数据库里是varchar ,自己手动强制转换一下,如果是 (string)$order_key; 如果是int,你也可能会出现这个问题,也需要转换一下(int)
5,
- location / {
- try_files $uri $uri/ /index.php?$query_string;
- index index.html index.htm index.php;
- #autoindex on;
- }
正常在NGINX的配置文件都需要加上这一段laravel才可以正常运行,但是直接从网上的找了一段是这样的
- location / {
- try_files /$uri /$uri/ /index.php?\$query_string;
- index index.html index.htm index.php;
- #autoindex on;
- }
坑爹导致 所有get参数都会现成
比如 index.php?type=ee
$this->request->all();
array{
[\type] => ee
}
还以为是laravel需要什么特殊处理,结果是配置文件出错
5,laravel意外bug
- #0 [internal function]: Illuminate\Foundation\Bootstrap\HandleExceptions->handleError(2, 'array_shift() e...', '/data/wwwroot/z...', 37, Array)
- #1 /data/wwwroot/zs_web/app/Repositories/SpiderRepository.php(37): array_shift(false)
- #2 /data/wwwroot/zs_web/app/Repositories/SpiderRepository.php(26): App\Repositories\SpiderRepository->cjysjs()
- #3 /data/wwwroot/zs_web/app/Console/Commands/SpiderTask.php(45): App\Repositories\SpiderRepository->do_all()
- #4 [internal function]: App\Console\Commands\SpiderTask->handle()
- #5 /data/wwwroot/zs_web/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(30): call_user_func_array(Array, Array)
- #6 /data/wwwroot/zs_web/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(87): Illuminate\Container\BoundMethod::Illuminate\Container\{closure}()
- #7 /data/wwwroot/zs_web/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(31): Illuminate\Container\BoundMethod::callBoundMethod(Object(Illuminate\Foundation\Application), Array, Object(Closure))
- #8 /data/wwwroot/zs_web/vendor/laravel/framework/src/Illuminate/Container/Container.php(539): Illuminate\Container\BoundMethod::call(Object(Illuminate\Foundation\Application), Array, Array, NULL)
- #9 /data/wwwroot/zs_web/vendor/laravel/framework/src/Illuminate/Console/Command.php(182): Illuminate\Container\Container->call(Array)
- #10 /data/wwwroot/zs_web/vendor/symfony/console/Command/Command.php(274): Illuminate\Console\Command->execute(Object(Symfony\Component\Console\Input\ArgvInput), Object(Illuminate\Console\OutputStyle))
- #11 /data/wwwroot/zs_web/vendor/laravel/framework/src/Illuminate/Console/Command.php(168): Symfony\Component\Console\Command\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Illuminate\Console\OutputStyle))
- #12 /data/wwwroot/zs_web/vendor/symfony/console/Application.php(952): Illuminate\Console\Command->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
- #13 /data/wwwroot/zs_web/vendor/symfony/console/Application.php(231): Symfony\Component\Console\Application->doRunCommand(Object(App\Console\Commands\SpiderTask), Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
- #14 /data/wwwroot/zs_web/vendor/symfony/console/Application.php(132): Symfony\Component\Console\Application->doRun(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
- #15 /data/wwwroot/zs_web/vendor/laravel/framework/src/Illuminate/Foundation/Console/Kernel.php(122): Symfony\Component\Console\Application->run(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
- #16 /data/wwwroot/zs_web/artisan(36): Illuminate\Foundation\Console\Kernel->handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
- #17 {main}
- array_shift(false)
导致这样的一个bug
代码会招致权限问题,我的天,经过分析是write的时候
- protected function write(array $record)
- {
- if (!is_resource($this->stream)) {
- if (null === $this->url || '' === $this->url) {
- throw new \LogicException('Missing stream url, the stream can not be opened. This may be caused by a premature call to close().');
- }
- $this->createDir();
- $this->errorMessage = null;
- set_error_handler(array($this, 'customErrorHandler'));
- $this->stream = fopen($this->url, 'a');
- if ($this->filePermission !== null) {
- @chmod($this->url, $this->filePermission);
- }
- restore_error_handler();
- if (!is_resource($this->stream)) {
- $this->stream = null;
- throw new \UnexpectedValueException(sprintf('The stream or file "%s" could not be opened: '.$this->errorMessage, $this->url));
- }
- }
- @chmod($this->url, $this->filePermission); 偶尔出现权限问题,不是可以重现bug
这个算是框架问题,唉,只能代码逻辑避免出现上面出现上面的代码错误,减少或者不写入错误写入日志
- @chmod($this->url, 0777); 就OK了
- 不改代码的方案是 crontab -e -u www
www 用户是php的用户,吧
* * * * * php /path/to/artisan schedule:run >> /dev/null 2>&1 写在里面就O
- 6,laravel 5.6 mews/captcha 使用小坑
注意版本
- 1. 安装
- 1). 使用 composer 安装:
- composer require mews/captcha
- 2). 修改 config/app 文件,添加 ServiceProvider:
- 在 providers 数组内追加如下内容
- 'providers' => [
- ...
- Mews\Captcha\CaptchaServiceProvider::class,
- ],
- 在 aliases 数组内追加如下内容
- 'aliases' => [
- ...
- 'Captcha' => Mews\Captcha\Facades\Captcha::class,
- ],
- 3). 运行 php artisan vendor:publish 生成配置文件 config/captcha.php
如果你这么操作了,新建一个CaptchaController去创建一个验证码,但是5.6不是这样的
你直接访问 http://127.0.0.1/captcha 就会去读取你生产的配置文件,不需要做任何操作
注意:你如果按照以前的比如5.4
- public function mews() {
- return Captcha::create('default');
- }
- 以前就是这样操作,访问一个新的路由,如果你还是这样做就无法按照
- config/captcha.php的配置生产你的需要的格式的验证码
- 7,5.6版本一些常见报错和原因
- Symfony \ Component \ HttpKernel \ Exception \ MethodNotAllowedHttpException
405 Method Not Allowed- 一般是因为路由 get post请求方式错误
- 419 unknown status
一般是发送的请求有 csrf-token校验 ,但是你没有发送csrf-token这个参数,注意查看http头是否带有csrf-token
Laravel开发采坑系列问题的更多相关文章
- Antd前端开发采坑记录
背景 基于页面友好,界面整洁美观:基于Antd框架开发虾能平台 选型 基于Antd-admin工程架构,进行开发:基于Antd+React+Umj 采坑记录 按照Html方式天机onClick方法,每 ...
- 小程序采坑系列-this.setData
今天踩了大坑,坑里还都是碎瓶渣子.. 先说一下基本使用.官网也有. 比如说你在main.js里面有这些变量.想修改某些值. data: { main_view_bgcolor: "" ...
- R语言采坑系列——Warning message: In validDetails.polygon(x) : 强制改变过程中产生了NA
用ggplot2的geom_density_2d时,总是不能填充图案,并报错: Warning message: In validDetails.polygon(x) : 强制改变过程中产生了NA 解 ...
- 关于在React中 报Super expression must either be null or a function, not undefined (采坑系列)
今天突然在联系React中遇到一开始就报 Super expression must either be null or a function, not undefined 百度,各种方法,.. ...
- cube+FreeRTOS联合开发采坑笔记
加了看门狗之后不断重启的可能 原因: 任务容量分配不足,在"FreeRTOSConfig.h"的配置中,有个configTOTAL_HEAP_SIZE中将堆大小调到最大.
- 基于 Laravel 开发博客应用系列 —— 设置 Linux/Mac 本地开发环境
1.不同 Linux 发行版本的区别 不同的 Linux 发行版本之间有一些细微区别,尤其是包管理器:CentOS 和 Fedora 使用 yum 作为包管理器,而Ubuntu 使用 apt,在 O ...
- 《神秘的程序员们》漫画26~28:《万年坑系列》 I、II、III(转)
26 <万年坑系列> I:那些令你憎恶的系统从何而来? 世界上总有一些令人憎恶的系统,而你却天天非用不可.这些系统的提供方们既不缺钱也不缺人,有的还很热衷于改版升级. 但为何升级完后,它们 ...
- Android项目开发填坑记-Fragment的onBackPressed
Github版 CSDN版 知识背景 Fragment在当前的Android开发中,有两种引用方式,一个是 Android 3.0 时加入的,一个是supportV4包中的.这里简称为Fragment ...
- 2-STM32带你入坑系列(点亮一个灯--Keil)
1-STM32带你入坑系列(STM32介绍) 首先是安装软件 这一节用Kei来实现,需要安装MDK4.7这个软件,怎么安装,自己百度哈.都学习32的人了,不会连个软件都不会安装吧....还是那句话 没 ...
随机推荐
- 基于git命令的代码统计方法
基于git命令的代码统计方法 没什么好说的,基于git log命令,使用前提是安装了git ...... .统计所有人代码量 统计所有人代码增删量,拷贝如下命令,直接在git bash等终端,git项 ...
- 使用 Nginx 为 Linux 实例绑定多个域名
KB: 41467 · 更新时间:2018-11-16 20:26:51 Nginx 是一款广泛应用的 Web 服务器,常用于反向代理.负载均衡器以及 HTTP 缓存等.本文以 CentOS ...
- 发现2017年最好的CSS框架
如今,无数的框架出现在定期而少数人喜欢自助,Foundation和angular.js主宰了整个世界的发展.CSS代表用于描述HTML(或XML)文档表示的样式表语言.一个框架被定义为一个包,它由一组 ...
- JAVA与C#的区别
Java和C#都是编程的语言,它们是两个不同方向的两种语言 相同点: 他们都是面向对象的语言,也就是说,它们都能实现面向对象的思想(封装,继承,多态) 区别: 1.c#中的命名空间是namespace ...
- 修改Linux用户配置之后先验证再退出
在服务器上更改完zsh.SSH连接属性.用户密码之后,我们可能想退出重新登录查看是否配置生效.这时,有一个注意事项:不要关闭旧窗口,而是重新打开一个新窗口尝试登录.否则,如果配置改错了,自己就再也没有 ...
- npm安装教程
一.使用之前,我们先来掌握3个东西是用来干什么的. npm: Nodejs下的包管理器. webpack: 它主要的用途是通过CommonJS的语法把所有浏览器端需要发布的静态资源做相应的准备,比如资 ...
- zabbix之微信告警(python版):微信个人报警,微信企业号告警脚本
微信个人告警脚本 微信个人告警:使用个人微信,发送到微信群组,微信好友 两个脚本执行: 1)能连接网络2)先执行server.py,扫描登录微信,登录之后没有报错,打开新终端查看端口是否起来了3)在z ...
- Android设备真实DPI与系统标示DPI——ldpi/mdpi/hdpi/xhdpi/xxhdpi/xxxhdpi
1.设备真实DPI与系统标示DPI 2.drawable允许的标示DPI值 drawable文件的合法名称如下: 3.如何验证 Demo如下,建立不同dpi的drawa ...
- Sublime Text 代码块注释
插件:DocBlockr /*回车:创建一个代码块注释 /**回车:在自动查找函数中的形参等等.
- Asp.Net WebApi上传图片
webapi using System; using System.Collections; using System.Collections.Generic; using System.Diagno ...