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
这个算是框架问题,唉,只能代码逻辑避免出现上面出现上面的代码错误,减少或者不写入错误写入日志
 核心原因是跑计划任务的用户是当前登陆用户,而php用户是www,偶尔会出现问题
 
@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开发采坑系列问题的更多相关文章

  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. Guava future

    减少主函数的等待时间,使得多任务能够异步非阻塞执行 ListenableFuture是可以监听的Future,它是对java原生Future的扩展增强.Future表示一个异步计算任务,当任务完成时可 ...

  2. Effective Java 第三版——88. 防御性地编写READOBJECT方法

    Tips 书中的源代码地址:https://github.com/jbloch/effective-java-3e-source-code 注意,书中的有些代码里方法是基于Java 9 API中的,所 ...

  3. vue前端知识点整理

    1. 说一下Vue的双向绑定数据的原理 vue 实现数据双向绑定主要是:采用数据劫持结合发布者-订阅者模式的方式,通过 Object.defineProperty() 来劫持各个属性的 setter, ...

  4. Delphi XE以后的版本 程序如何瘦身

    第一步:关闭debug infomation. 打开工程后,依次点击project--option--delphi compiler--linking 将右边Debug information改为Fa ...

  5. Spring Boot项目的接口防刷

    说明:使用了注解的方式进行对接口防刷的功能,非常高大上,本文章仅供参考 一,技术要点:springboot的基本知识,redis基本操作, 首先是写一个注解类: import java.lang.an ...

  6. 测试创建表变量对IO的影响

    测试创建表变量前后,tempdb的空间大小,目前使用sp_spaceused得到大小,也可以使用视图sys.dm_db_file_space_usage use tempdb go Set nocou ...

  7. Mac 开发必备 利器 iterm2 oh-my-zsh

    推荐终端神器 iterm2 以及 oh-my-zsh,可以研究一下怎么用,好的开发环境是可以提高效率的,以及alias 的使用. https://www.zhihu.com/question/2744 ...

  8. msm audio platform 驱动代码跟踪

    sound/soc/soc-core.c static int __init snd_soc_init(void) { #ifdef CONFIG_DEBUG_FS snd_soc_debugfs_r ...

  9. VS IISExpress REST DELETE 405 Method Not Allowed

    [参考].net IIS MVC Rest api 跨域 PUT DELETE 404 无法使用问题解决方案 今日在使用泛型處理常式處理檔案上傳時,使用了 HTTP 動詞的 PUT.DELETE 進行 ...

  10. Java代码中解压RAR文件

    import java.io.File; import java.io.FileOutputStream; import de.innosystec.unrar.Archive; import de. ...