2017年12月22日17:40:03 不定時更新php
版本5.4.Xcss
一下是可能會遇到的坑html
1,必須的寫路由轉發才能訪問控制器,固然你能夠自動路由訪問,可是須要些匹配規則,其實仍是轉發了laravel
好多人討論過自動路由的缺點,可是中小項目用不上,並且暴露在外的接口,如今大多數都是有路由轉發,徹底能夠經過分組來兼容多種開發習慣和需求,並非自動路由就狗屁不是web
2,Laravel 作計劃任務的時候坑真的好多,好比不能直接跨控制器訪問,web的是web的路由,console是它本身的,因此你的功能和邏輯代碼必須在Repository或者service裏面,否則你懂的,作好邏輯代碼分離數據庫
官方文檔只有用過的才能看得懂,我很無奈json
完整流程windows
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