這份整理拖太久了,到 PHP 8.2 都上線了還沒寫完,所以就整理到 7.x 結束吧。
PHP 從約 5.2 版就開始慢慢的加上一些重大的改變,像是 PHP v5.3 開始支援 `namespace` 之後,開始有了 composer 各種套件系統的發展。這些改變讓 PHP 的開發和維護更方便、更簡單。以下記錄各版本重要的功能,以便在更新程式時可以更快的了解有什麼需要留意的事項。
備註:我沒用過 PHP 4.x,如果你還在用的話,請多保重 ….
軟體開發、伺服器和生活瑣事
這份整理拖太久了,到 PHP 8.2 都上線了還沒寫完,所以就整理到 7.x 結束吧。
PHP 從約 5.2 版就開始慢慢的加上一些重大的改變,像是 PHP v5.3 開始支援 `namespace` 之後,開始有了 composer 各種套件系統的發展。這些改變讓 PHP 的開發和維護更方便、更簡單。以下記錄各版本重要的功能,以便在更新程式時可以更快的了解有什麼需要留意的事項。
備註:我沒用過 PHP 4.x,如果你還在用的話,請多保重 ….
新版本的 phpMyAdmin 預設會將資料表過多的清單分頁,以便加快頁面載入速度,但其資料表 filter / searching 只會針對當下的分頁進行搜尋,塑資料表在第二頁或後面的分頁,則會搜尋不到資料。
若希望 phpMyAdmin 在資料表清單中不要分頁,可以在 config.inc.php 設定檔最後新增參數:
$cfg['MaxTableList'] = 1000;
今天遇到錯誤訊息耽誤了很久:
... foreign key constraint 'xxx_id_foreign' are incompatible.
錯誤訊息沒有詳細列出可能的錯誤,追了很久才知道有一些地方要注意。
More “Laravel Migration 出現 foreign key constraint in complete 注意事項” »
網路上多數都說需要 unique ID 的話用 uniqid()
產生即可,不過事實上這個方法產生的亂度不夠亂,特殊情空下是可以用猜的猜到:
foreach(range(1,10) as $n) { echo uniqid() . "\n"; }
$ php uid.php 62283582750d2 62283582750de 62283582750df 62283582750e0 62283582750e1 62283582750e2 62283582750e3 62283582750e4 62283582750e5 62283582750e6
如果需要亂度夠大的 ID,官方建議使用 random_bytes()
等函式來實作:
foreach(range(1,10) as $n) { echo bin2hex(random_bytes(8)) . "\n"; }
$ php uid.php 8deaa97f2cc4709d f2c556361d316f8d bcf97aa28e6b5a02 7453b298b1f748e5 6478265fb8da5c01 4981729191162649 80a7a2824818addf 622009f43ec32836 3b4d757e1894702c 4a254e226179e3b5
Laravel 和 Lumen 都有自己整理好的一套 unit test framework,因此若要加入 AspectMock 會需要對預設的 boostrap file 做一些調整。
整合時需要注意的事情:
/bootstrap/app.php
phpunit.xml
中的 bootstrap config,要改成自己新建立的 bootstrap filerequire
順序,不要讓 Laravel App 的資料被覆蓋掉 (另外也要注意 require
和 require_once
的差異)建立新的 bootstrap 設定檔 /tests/bootstrap.php
:
<?php // composer autoload require_once __DIR__.'/../vendor/autoload.php'; // load Laravel bootstrap $app = require_once __DIR__ . '/../bootstrap/app.php'; // create temporary folder for AspectMock $tmpPath = '/tmp/aspectMock/'; if (!file_exists($tmpPath)) { mkdir($tmpPath, 0777); } $kernel = \AspectMock\Kernel::getInstance(); $kernel->init([ 'appDir' => __DIR__ . '/..', 'debug' => true, 'includePaths' => [ __DIR__ . '/../app', __DIR__ . '/../vendor/laravel', // 如果需要 mock Model 則加上這行 ], 'excludePaths' => __DIR__, // "/tests" 目錄不需要處理 'cacheDir' => $tmpPath, ]); return $app; // 把 App 回傳給 createApplication()
接下來要調整原有的 phpunit.xml
設定檔,需要參考 AspectMock 的要求,來調整:
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="./vendor/phpunit/phpunit/phpunit.xsd" bootstrap="tests/bootstrap.php" backupGlobals="false">
注意最後面二行,bootstrap
要改成剛剛新建立的檔案,backupGlobals
則要關閉。
最後,去調整 BaseTest.php
,在 tearDown()
加上 AspectMock 清理設定的指令:
protected function tearDown(): void { test::clean(); }
另外在 createApplication()
這邊,要改用上面建立的 bootstrap file:
public function createApplication() { return require __DIR__ . '/bootstrap.php'; }
以上全部改好的話,執行 vendor/bin/phpunit
應該可以正常運作。
注意 require
和 require_once
的差異,Laravel 會在每次開始 unit test 之前,重新建立 $app
,所以用 require_once
的話,就的設定清不掉
-$app = require_once __DIR__ . '/../bootstrap/app.php'; // Laravel bootstrap +$app = require __DIR__ . '/../bootstrap/app.php';