2017年12月22日17:40:03 不定时更新

版本5.4.X

一下是可能会遇到的坑

1,必须的写路由转发才能访问控制器,当然你可以自动路由访问,但是需要些匹配规则,其实还是转发了

好多人讨论过自动路由的缺点,但是中小项目用不上,而且暴露在外的接口,现在大多数都是有路由转发,完全可以通过分组来兼容多种开发习惯和需求,并不是自动路由就狗屁不是

2,Laravel 做计划任务的时候坑真的好多,比如不能直接跨控制器访问,web的是web的路由,console是它自己的,所以你的功能和逻辑代码必须在Repository或者service里面,不然你懂的,做好逻辑代码分离

官方文档只有用过的才能看得懂,我很无奈

完整流程

app\Console\Commands下建立你的任务文件

  1. SpiderTask.php
  1. <?php
  2.  
  3. namespace App\Console\Commands;
  4.  
  5. use Illuminate\Console\Command;
  6. //use Illuminate\Support\Facades\Redis;
  7. use App\Repositories\SpiderRepository;//具体逻辑代码
  8.  
  9. class SpiderTask extends Command {
  10.  
  11. protected $taskserver;
  12.  
  13. /**
  14. * The name and signature of the console command.
  15. *
  16. * @var string
  17. */
  18. protected $signature = 'SpiderTask';
  19.  
  20. /**
  21. * The console command description.
  22. *
  23. * @var string
  24. */
  25. protected $description = 'spider every one hour crawl data';
  26. protected $spider;
  27.  
  28. /**
  29. * Create a new command instance.
  30. *
  31. * @return void
  32. */
  33. public function __construct() {
  34.  
  35. parent::__construct();
  36. $this->spider = new SpiderRepository();
  37. }
  38.  
  39. /**
  40. * Execute the console command.
  41. *
  42. * @return mixed
  43. */
  44. public function handle() {
  45. $this->spider->do_all();//具体执行地方
  46. }
  47.  
  48. }

然后注册到Kernel.php

  1. <?php
  2.  
  3. namespace App\Console;
  4.  
  5. use Illuminate\Console\Scheduling\Schedule;
  6. use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
  7. use App\Repositories\SpiderRepository;//我的具体逻辑代码地方
  8.  
  9. class Kernel extends ConsoleKernel {
  10.  
  11. /**
  12. * The Artisan commands provided by your application.
  13. *
  14. * @var array
  15. */
  16. protected $commands = [
  17. //
  18. 'App\Console\Commands\SpiderTask', //必须
  19. ];
  20.  
  21. /**
  22. * Define the application's command schedule.
  23. *
  24. * @param \Illuminate\Console\Scheduling\Schedule $schedule
  25. * @return void
  26. */
  27. protected function schedule(Schedule $schedule) {
  28. // $schedule->call(function () {
  29. // $Spider = new SpiderRepository();
  30. // $Spider->do_all();
  31. // })->daily();
  32. $schedule->command('SpiderTask')->daily();
    //两种方法都可以,建议第二种,逻辑更清晰
  33. }
  34.  
  35. /**
  36. * Register the Closure based commands for the application.
  37. *
  38. * @return void
  39. */
  40. protected function commands() {
  41. require base_path('routes/console.php');
  42. }
  43.  
  44. }

注意:

你要测试你的代码逻辑有没有错误

最好在Linux下测试,因为windows好多问题

在代码根目录,如果命令没有到全局,使用完整路径

  1. php artisan schedule:run

everyMinute才会实时运行,可以看到报错

  1. $schedule->command('SpiderTask')->everyMinute();

http://laravelacademy.org/post/6931.html 官方文档

  1. <?php
  2.  
  3. namespace App\Repositories;
  4.  
  5. use App\Models\Spider;
  6. //use phpspider\core\phpspider;
  7. use phpspider\core\requests;
  8. use phpspider\core\selector;
  9.  
  10. class SpiderRepository {
  11.  
  12. use BaseRepository;
  13.  
  14. protected $model;
  15.  
  16. /**
  17. * ActivityRepository constructor.
  18. * @param Activity $activity
  19. */
  20. public function __construct() {
  21. $this->model = new Spider();
  22. }
  23.  
  24. public function do_all() {
  25. $this->cjysjs();
  26. $this->shysjs();
  27. $this->nchn();
  28. $this->ltbj();
  29. }
  30.  
  31. //长江有色金属
  32. public function cjysjs() {
  33. $html = requests::get('http://www.ccmn.cn/');
  34. $data = selector::select($html, "#40288092327140f601327141c0560001", "css");
  35. $data1 = selector::select($data, "tr", "css");
  36. array_shift($data1);
  37.  
  38. $array = array();
  39. if (!empty($data1) && is_array($data1)) {
  40. foreach ($data1 as $k => &$v) {
  41. $data2 = selector::select($v, "td", "css");
  42. foreach ($data2 as $kk => &$vv) {
  43. $vv = str_replace('
  44. ', '', $vv);
  45. $vv = str_replace(array("\r\n", "\r", "\n"), "", $vv);
  46. $vv = trim($vv);
  47. }
  48. $data2['3'] = selector::select($data2['3'], "font", "css");
  49. unset($data2['6']);
  50. $array[] = $data2;
  51. }
  52.  
  53. if (empty($array)) {
  54. $info = date("Y-m-d H:i:s", time()) . ':长江有色金属抓取失败!';
  55. Log::info($info);
  56. }
  57. $name = 'cjysjs';
  58. $_data = [];
  59. if (!empty($array) && is_array($array)) {
  60. $_data['value'] = json_encode($array);
  61. $_data['crawl_time'] = time();
  62.  
  63. $count = $this->getData($name);
  64. if (empty($count)) {
  65. //增加
  66. $_data['name'] = $name;
  67. $result = $this->saveData(null, $_data);
  68. } else {
  69. //更新
  70. $_data['name'] = $name;
  71. $result = $this->saveData($name, $_data);
  72. }
  73. }
  74. }
  75. }
  76.  
  77. public function saveData($name = null, $data = null) {
  78. return $this->model->updateOrCreate(['name' => $name], $data);
  79. }
  80.  
  81. public function getData($name) {
  82. return $this->model->where('name', $name)->count();
  83. }
  84.  
  85. }

添加计划任务

  1. * * * * * php /path/to/artisan schedule:run >> /dev/null 2>&1
  1. /dev/null 2>&1 必须,其实为了把错误信息和输出输出到/dev/null 文件
    注意php是否是全局,不是就全路径,artisan网站根目录
  2.  
  3. 获取错误
  1. Laravel 调度器为处理调度任务输出提供了多个方便的方法。首先,使用sendOutputTo 方法,你可以发送输出到文件以便稍后检查:
  2.  
  3. $schedule->command('emails:send')
  4. ->daily()
  5. ->sendOutputTo($filePath);
  6. 如果你想要追加输出到给定文件,可以使用 appendOutputTo 方法:
  7.  
  8. $schedule->command('emails:send')
  9. ->daily()
  10. ->appendOutputTo($filePath);
  11. 使用 emailOutputTo 方法,你可以将输出发送到电子邮件。使用电子邮件发送任务输出之前,需要配置 Laravel 的电子邮件服务:
  12.  
  13. $schedule->command('foo')
  14. ->daily()
  15. ->sendOutputTo($filePath)
  16. ->emailOutputTo('foo@example.com');

3,laravel增加第三类或者库文件

lavavel是封装的比较好的框架,那么composer,要么遵循他的规范,我在使用tcpdf在laravel5.4的时候,发现一个问题

laravel的某种组件要php7以上版本,服务器上又只有5.6我又不想麻烦,想直接引入tcpdf,发现完全不行,la回去直接通过空间路径去引入文件读取,

这样一来,就不能直接引入,解决方案不难,也不用升级php版本,

  1. composer.json
  2.  
  3. "autoload": {
  4. "classmap": [
  5. "database",
  6. "app/Libarary/tcpdf"
  7. ],
  8. "psr-4": {
  9. "App\\": "app/"
  10. },
  11. "files": [
  12. "app/Tools.php",
  13. "app/WeiXin.php"
  14. ]
  15. },

我引入tcpdf在app下面的/Libarary/tcpdf

然后

composer dumpautoload

注意,如果你本地composer比较麻烦,你可以在虚拟机上执行,在吧代码拉回来,因为windows上实在难用

代码使用比较简单

  1. use TCPDF;
  2.  
  3. public function index() {
  4. $pdf = new TCPDF(PDF_PAGE_ORIENTATION, PDF_UNIT, PDF_PAGE_FORMAT, true, 'UTF-8', false);
  5. }

就OK了

4,在某些特殊环境下模型的 create方法,会把很大的数字 2018011900012 转换成 -622729113的负数,数据库存的string varchar,底层原因未知

解决方法,如果数据库里是varchar ,自己手动强制转换一下,如果是 (string)$order_key; 如果是int,你也可能会出现这个问题,也需要转换一下(int)

5,

  1. location / {
  2. try_files $uri $uri/ /index.php?$query_string;
  3. index index.html index.htm index.php;
  4. #autoindex on;
  5. }

正常在NGINX的配置文件都需要加上这一段laravel才可以正常运行,但是直接从网上的找了一段是这样的

  1. location / {
  2. try_files /$uri /$uri/ /index.php?\$query_string;
  3. index index.html index.htm index.php;
  4. #autoindex on;
  5. }

坑爹导致 所有get参数都会现成

比如 index.php?type=ee

$this->request->all();

array{

[\type] => ee

}

还以为是laravel需要什么特殊处理,结果是配置文件出错

5,laravel意外bug

  1. #0 [internal function]: Illuminate\Foundation\Bootstrap\HandleExceptions->handleError(2, 'array_shift() e...', '/data/wwwroot/z...', 37, Array)
  2. #1 /data/wwwroot/zs_web/app/Repositories/SpiderRepository.php(37): array_shift(false)
  3. #2 /data/wwwroot/zs_web/app/Repositories/SpiderRepository.php(26): App\Repositories\SpiderRepository->cjysjs()
  4. #3 /data/wwwroot/zs_web/app/Console/Commands/SpiderTask.php(45): App\Repositories\SpiderRepository->do_all()
  5. #4 [internal function]: App\Console\Commands\SpiderTask->handle()
  6. #5 /data/wwwroot/zs_web/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(30): call_user_func_array(Array, Array)
  7. #6 /data/wwwroot/zs_web/vendor/laravel/framework/src/Illuminate/Container/BoundMethod.php(87): Illuminate\Container\BoundMethod::Illuminate\Container\{closure}()
  8. #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))
  9. #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)
  10. #9 /data/wwwroot/zs_web/vendor/laravel/framework/src/Illuminate/Console/Command.php(182): Illuminate\Container\Container->call(Array)
  11. #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))
  12. #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))
  13. #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))
  14. #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))
  15. #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))
  16. #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))
  17. #16 /data/wwwroot/zs_web/artisan(36): Illuminate\Foundation\Console\Kernel->handle(Object(Symfony\Component\Console\Input\ArgvInput), Object(Symfony\Component\Console\Output\ConsoleOutput))
  18. #17 {main}
  1. array_shift(false)

导致这样的一个bug

代码会招致权限问题,我的天,经过分析是write的时候

  1. protected function write(array $record)
  2. {
  3. if (!is_resource($this->stream)) {
  4. if (null === $this->url || '' === $this->url) {
  5. throw new \LogicException('Missing stream url, the stream can not be opened. This may be caused by a premature call to close().');
  6. }
  7. $this->createDir();
  8. $this->errorMessage = null;
  9. set_error_handler(array($this, 'customErrorHandler'));
  10. $this->stream = fopen($this->url, 'a');
  11. if ($this->filePermission !== null) {
  12. @chmod($this->url, $this->filePermission);
  13. }
  14. restore_error_handler();
  15. if (!is_resource($this->stream)) {
  16. $this->stream = null;
  17. throw new \UnexpectedValueException(sprintf('The stream or file "%s" could not be opened: '.$this->errorMessage, $this->url));
  18. }
  19. }
  1. @chmod($this->url, $this->filePermission); 偶尔出现权限问题,不是可以重现bug
    这个算是框架问题,唉,只能代码逻辑避免出现上面出现上面的代码错误,减少或者不写入错误写入日志
 核心原因是跑计划任务的用户是当前登陆用户,而php用户是www,偶尔会出现问题
 
  1. @chmod($this->url, 0777); OK
  2.  
  3. 不改代码的方案是 crontab -e -u www
    www 用户是php的用户,吧
  1. * * * * * php /path/to/artisan schedule:run >> /dev/null 2>&1 写在里面就O
  1. 6laravel 5.6 mews/captcha 使用小坑
    注意版本
  1. 1. 安装
  2. 1). 使用 composer 安装:
  3.  
  4. composer require mews/captcha
  5.  
  6. 2). 修改 config/app 文件,添加 ServiceProvider
  7.  
  8. providers 数组内追加如下内容
  9.  
  10. 'providers' => [
  11. ...
  12. Mews\Captcha\CaptchaServiceProvider::class,
  13. ],
  14.  
  15. aliases 数组内追加如下内容
  16.  
  17. 'aliases' => [
  18. ...
  19. 'Captcha' => Mews\Captcha\Facades\Captcha::class,
  20. ],
  21.  
  22. 3). 运行 php artisan vendor:publish 生成配置文件 config/captcha.php

如果你这么操作了,新建一个CaptchaController去创建一个验证码,但是5.6不是这样的

你直接访问 http://127.0.0.1/captcha  就会去读取你生产的配置文件,不需要做任何操作

注意:你如果按照以前的比如5.4

  1. public function mews() {
  2.  
  3. return Captcha::create('default');
  4. }
  1. 以前就是这样操作,访问一个新的路由,如果你还是这样做就无法按照
  1. config/captcha.php的配置生产你的需要的格式的验证码
  2.  
  3. 7,5.6版本一些常见报错和原因
  1. Symfony \ Component \ HttpKernel \ Exception \ MethodNotAllowedHttpException
    405 Method Not Allowed
  2.  
  3. 一般是因为路由 get post请求方式错误
  1. 419 unknown status
    一般是发送的请求有 csrf-token校验 ,但是你没有发送csrf-token这个参数,注意查看http头是否带有csrf-token
  1.  

Laravel开发采坑系列问题的更多相关文章

  1. Antd前端开发采坑记录

    背景 基于页面友好,界面整洁美观:基于Antd框架开发虾能平台 选型 基于Antd-admin工程架构,进行开发:基于Antd+React+Umj 采坑记录 按照Html方式天机onClick方法,每 ...

  2. 小程序采坑系列-this.setData

    今天踩了大坑,坑里还都是碎瓶渣子.. 先说一下基本使用.官网也有. 比如说你在main.js里面有这些变量.想修改某些值. data: { main_view_bgcolor: "" ...

  3. R语言采坑系列——Warning message: In validDetails.polygon(x) : 强制改变过程中产生了NA

    用ggplot2的geom_density_2d时,总是不能填充图案,并报错: Warning message: In validDetails.polygon(x) : 强制改变过程中产生了NA 解 ...

  4. 关于在React中 报Super expression must either be null or a function, not undefined (采坑系列)

    今天突然在联系React中遇到一开始就报    Super expression must either be null or a function, not undefined 百度,各种方法,.. ...

  5. cube+FreeRTOS联合开发采坑笔记

    加了看门狗之后不断重启的可能 原因: 任务容量分配不足,在"FreeRTOSConfig.h"的配置中,有个configTOTAL_HEAP_SIZE中将堆大小调到最大.

  6. 基于 Laravel 开发博客应用系列 —— 设置 Linux/Mac 本地开发环境

    1.不同 Linux 发行版本的区别 不同的 Linux 发行版本之间有一些细微区别,尤其是包管理器:CentOS 和 Fedora 使用 yum 作为包管理器,而Ubuntu 使用  apt,在 O ...

  7. 《神秘的程序员们》漫画26~28:《万年坑系列》 I、II、III(转)

    26 <万年坑系列> I:那些令你憎恶的系统从何而来? 世界上总有一些令人憎恶的系统,而你却天天非用不可.这些系统的提供方们既不缺钱也不缺人,有的还很热衷于改版升级. 但为何升级完后,它们 ...

  8. Android项目开发填坑记-Fragment的onBackPressed

    Github版 CSDN版 知识背景 Fragment在当前的Android开发中,有两种引用方式,一个是 Android 3.0 时加入的,一个是supportV4包中的.这里简称为Fragment ...

  9. 2-STM32带你入坑系列(点亮一个灯--Keil)

    1-STM32带你入坑系列(STM32介绍) 首先是安装软件 这一节用Kei来实现,需要安装MDK4.7这个软件,怎么安装,自己百度哈.都学习32的人了,不会连个软件都不会安装吧....还是那句话 没 ...

随机推荐

  1. 基于git命令的代码统计方法

    基于git命令的代码统计方法 没什么好说的,基于git log命令,使用前提是安装了git ...... .统计所有人代码量 统计所有人代码增删量,拷贝如下命令,直接在git bash等终端,git项 ...

  2. 使用 Nginx 为 Linux 实例绑定多个域名

    KB: 41467 · 更新时间:2018-11-16 20:26:51     Nginx 是一款广泛应用的 Web 服务器,常用于反向代理.负载均衡器以及 HTTP 缓存等.本文以 CentOS ...

  3. 发现2017年最好的CSS框架

    如今,无数的框架出现在定期而少数人喜欢自助,Foundation和angular.js主宰了整个世界的发展.CSS代表用于描述HTML(或XML)文档表示的样式表语言.一个框架被定义为一个包,它由一组 ...

  4. JAVA与C#的区别

    Java和C#都是编程的语言,它们是两个不同方向的两种语言 相同点: 他们都是面向对象的语言,也就是说,它们都能实现面向对象的思想(封装,继承,多态) 区别: 1.c#中的命名空间是namespace ...

  5. 修改Linux用户配置之后先验证再退出

    在服务器上更改完zsh.SSH连接属性.用户密码之后,我们可能想退出重新登录查看是否配置生效.这时,有一个注意事项:不要关闭旧窗口,而是重新打开一个新窗口尝试登录.否则,如果配置改错了,自己就再也没有 ...

  6. npm安装教程

    一.使用之前,我们先来掌握3个东西是用来干什么的. npm: Nodejs下的包管理器. webpack: 它主要的用途是通过CommonJS的语法把所有浏览器端需要发布的静态资源做相应的准备,比如资 ...

  7. zabbix之微信告警(python版):微信个人报警,微信企业号告警脚本

    微信个人告警脚本 微信个人告警:使用个人微信,发送到微信群组,微信好友 两个脚本执行: 1)能连接网络2)先执行server.py,扫描登录微信,登录之后没有报错,打开新终端查看端口是否起来了3)在z ...

  8. Android设备真实DPI与系统标示DPI——ldpi/mdpi/hdpi/xhdpi/xxhdpi/xxxhdpi

    1.设备真实DPI与系统标示DPI 2.drawable允许的标示DPI值         drawable文件的合法名称如下: 3.如何验证         Demo如下,建立不同dpi的drawa ...

  9. Sublime Text 代码块注释

    插件:Doc​Blockr /*回车:创建一个代码块注释 /**回车:在自动查找函数中的形参等等.

  10. Asp.Net WebApi上传图片

    webapi using System; using System.Collections; using System.Collections.Generic; using System.Diagno ...