PHP 7.2 からは create_function が内部でeval()を実行していて、セキュリティ上危ないということで廃止され、エラー表示となります。 そこで以下のようにクロージャで置き換えます。
例:create_function() を クロージャで置き換える
$v = preg_replace_callback('/\[?(https?:\/\/[^ ^ ]+)(:title=([^\]]*))?\]?/',
create_function('$m', '
return "<a href=\"{$m[1]}\" target=\"_blank\" >"
. (isset($m[3]) ? $m[3] : $m[1] )
. "</a>";
'),
$v);
↓
$v = preg_replace_callback('/\[?(https?:\/\/[^ ^ ]+)(:title=([^\]]*))?\]?/',
function ($m) {
return "<a href=\"{$m[1]}\" target=\"_blank\" >" . (isset($m[3]) ? $m[3] : $m[1]) . "</a>";
},
$v);
クロージャ内に変数を渡す場合は set を使用して渡します。
IEやEdgeでhistory.back()や「戻る」ボタンで戻った時に消える時の対処法
PHPでセッションの使用 session_start(); を実行すると、ブラウザのHTTPヘッダには
Expires: Thu, 19 Nov 1981 08:52:00 GMT
Cache-Control: no-store, no-cache, must-revalidate, post-check=0, pre-check=0
Pragma: no-cache
というのが必ず送られます。
これが送られるとそのページはキャッシュされないので、例えばフォーム入力画面の場合
次の確認画面から history.back(); で返ってくると、入力欄が消えてしまいます。
(ただし Google Chrome の場合は消えない場合が多いので、必ずIEやEdgeで確認しましょう。)
そこで 次の方法で対処できます。
session_start();
// セッション使用時にブラウザキャッシュを有効にする
header('Expires: -1');
header('Cache-Control:');
header('Pragma:');
記述場所は 「session_start() の後」かつ「何か画面に出力する前」です。
session_cache_limiter('public'); // セッション使用時にキャッシュを使えるようにする
// ↓PHPのデフォルト値は 180 です
session_cache_expire(60); // セッション時のキャッシュ有効時間 60分(1時間)
session_start();
とすると、セッション使用時にもキャッシュ可能になります。
session_cache_limiterの引数 | 説明 |
---|---|
none | no-cacheヘッダを送信しない |
nocache | no-cacheヘッダを送信する |
private | キャッシュを利用する(プロキシサーバーにはキャッシュを利用させない) |
private_no_expire | キャッシュを利用する(プロキシサーバーにはキャッシュを利用させない) |
public | キャッシュを利用する |
ちなみにセッション自体の有効時間は
ini_set("session.cookie_lifetime", 28800); // セッション有効時間 60*60*8(8時間)
として指定します。
phpでユニットテストを行うときはPHPUnitがお勧めですが, PEARの run-tests( .phpt ) というのもあるので紹介しておきます。
PEARがインストールされていれば使えるので PEAR をインストールします。
composer require pear/pear
例 : m.php
<?php
function implode_recursive($glue, array $pieces) {
$result = array();
array_walk_recursive($pieces, function($value) use(&$result) {
$result[] = $value;
});
return implode($glue, $result);
}
テストファイルをディレクトリ tests/ 以下に作成します。ファイル名は 001.phpt とします。
例 : tests/001.phpt
--TEST--
test 001
--FILE--
<?php
require __DIR__ . '/../m.php';
$test = array(
"hoge",
"fuga",
array(
array(
1,
2,
),
"foo",
"bar",
array(),
"qux",
),
"piyo",
);
var_dump(implode_recursive(",", array()));
var_dump(implode_recursive(",", $test));
var_dump(implode_recursive("", $test));
?>
--EXPECT--
string(0) ""
string(30) "hoge,fuga,1,2,foo,bar,qux,piyo"
string(23) "hogefuga12foobarquxpiyo"
書き方は次のようになっています
--TEST--
コメント
--FILE--
phpによる標準出力への出力
--EXPECT--
予想される結果
これで「phpによる標準出力への出力」と「予想される結果」を単純に比較してくれます
コマンドラインから以下のように実行します
cd tests/
pear run-tests
これだけで フォルダ内の全ての .phpt ファイルを読み込んでテストを実行します。
テスト結果
Running 1 tests
PASS test 001[001.phpt]
TOTAL TIME: 00:01
1 PASSED TESTS
0 SKIPPED TESTS
以下のようにするとテストが失敗した時に色がついて表示されるのでオススメです
pear run-tests | grep --color=auto -i -e 'fail' -e'$'
以下のようにエイリアスを作成しておくと phpt と入力するだけでテストが走るので便利です
vi ~/.bash_profile
alias phpt="pear run-tests | grep --color=auto -i -e 'fail' -e'$'"
php7から変数の型宣言が厳格なコーディングが可能になっていますのでぜひ使いましょう。
echo gettype( $val );
var_dump( $val );
declare(strict_types=1);
<?php
declare(strict_types=1);
function my_func(int $v){
echo $v."\n";
}
my_func('999');
PHP Fatal error: Uncaught TypeError: Argument 1 passed to my_func() must be of the type integer, string given, called in /test.php on line 6 and defined in /test.php:3
Stack trace:
#0 /test.php(3): my_func('999')
#1 {main}
thrown in /test.php on line 7
こちらもあわせて使用すると非常に有効です。
PHPで列挙型(enum)を作る
http://bit.ly/2oTfrz7
多人数が関わるプロジェクトでは phpコードの書式を統一するのが難しくなります。
そこでプログラマー個人にコーディングルールを覚えさせるよりプログラムで自動判別させます。
下記の phpcs がとても便利です。
https://github.com/squizlabs/PHP_CodeSniffer/wiki
composer global require "squizlabs/php_codesniffer=*"
echo 'export PATH=$HOME/.composer/vendor/bin:$PATH' >> .bash_profile
source .bash_profile
phpcs --version
PSR2準拠のソースフォーマットチェックを行います。
phpcs --report=source --standard=PSR2 [phpファイル名 または ディレクトリ名 ]
オプション --standard=PSR2 を付け忘れないようにしましょう。
(オプションをつけないとPEAR準拠のソースフォーマットチェックとなります)
--reportオプションは
--report=source
--report=summary
があります。
phpcs -i
例
The installed coding standards are MySource, PEAR, PHPCS, PSR1, PSR2, Squiz and Zend
指定したコーディング規約に沿うようphpソースコードを自動で整形してくれます
例)PSR2準拠に自動整形します
phpcbf --standard=PSR2 [phpファイル名]
バグにつながりそうな怪しい ソースコードをチェックして教えてくれる php md。
コーディング時に必ず使うようにしておくとミスやバグが減るので是非使いましょう
composer global require phpmd/phpmd
echo 'export PATH=$HOME/.composer/vendor/bin:$PATH' >> .bash_profile
source .bash_profile
phpmd --version
(ソースファイル myfile.php チェックしテキストデータで結果を受け取る。チェックする項目は
codesize,controversial,design,naming,unusedcode)
phpmd myfile.php text codesize,design,naming,unusedcode
オプションの意味
codesize コードが大きすぎないかチェック
controversial 命名規則など議論の余地がある部分を検出するチェック
design 設計上の関連のチェック
naming 変数名など名前関連のチェック
unusedcode 使われていない変数のチェック
cleancode 綺麗なコードかチェック
書式は以下の通りです
phpmd (phpファイル名) ( text または xml または html ) (オプションをカンマで区切る)
引用 : https://simple-it-life.com/?p=761
次のパッケージをインストールします
SublimeLinter
SublimeLinter-phpmd
【Package Settings】→【SublimeLinter】→【Settings - User】に記述があります。
設定例: (ルールセットから controversial, design, naming を取り除いています)
"linters": {
"phpmd": {
"@disable": false,
"args": [],
"excludes": [],
"delay": 0.75,
"rulesets": "cleancode,codesize,unusedcode"
}
}
また反応速度が速いとオートコンプリートと機能がバッティングしてしまうので、SublimeLinterのDelayの値を少し多めにしてやると良いと思います
設定例: ディレイ値を増やす
"delay": 0.75,
これで PHPファイルを開いているときに自動的にソースのおかしそうなところを指摘してくれます。
@todo をハイライト表示してくれるのでとても便利です。
PHPMDのエラーを回避したい場合は、ソースコードの クラス名またはメソッドの上に PHPDOC 形式で SuppressWarnings を指定することで エラー表示を回避することが出来ます。 指定できる文字列は (PHPMD.XXXXX) という形式で、XXXXXに指定する文字列はこちらのページから調べることが出来ます。
https://phpmd.org/rules/index.html
例)StaticAccess と ElseExpression 2つのエラーを表示しないようにします
/**
* @SuppressWarnings(PHPMD.StaticAccess)
* @SuppressWarnings(PHPMD.ElseExpression)
*/
public function hogehoge( $arg )
{
// code ...
}
PHP5.6以降では配列関係の参照渡しの関数にデータを渡す時は一度変数に入れる必要があります。
$new_array = end( array_keys($array) );
$ar_key = array_keys($array);
$new_array = end( $ar_key );
PHP5.6以上では
iconv_set_encoding('output_encoding', 'UTF-8');
は下記のようなエラーとなります
Deprecated: iconv_set_encoding(): Use of iconv.internal_encoding is deprecated in xxxxx.php on line 99
とりあえずエラーを消したい場合は以下のように一括で置換するといいでしょう
iconv_set_encoding('output_encoding', 'UTF-8');
↓
if ( (float)phpversion() < 5.6 ){ iconv_set_encoding('output_encoding', 'UTF-8'); }
PHP5.6ではstaticではないメソッドを直接呼び出すとエラーが出ます。
■ 例:PHP5.6では以下のコードはエラーとなる
$config = Spyc::YAMLLoad($yml_filename);
■ 対処法: 以下のようにコードを変更します。
$spyc = new Spyc();
$config = $spyc->YAMLLoad($yml_filename);
PHP 5.4からは 5.3までは出力されなかった【E_STRICTエラー】がデフォルトで出力されるようになっています。 なのでPHPのバージョンを 5.3以下から5.4以上に上げるとE_STRICTエラーが表示されることがよくあります。
自分で書いたソースの場合はエラーの内容を調べて修正するのが一番よいでしょう。
http://goo.gl/moKrOg
そもそもPHPのバージョンが5.3以下の場合は出力されてなかったエラーなので、そもそもエラーを表示させないという手法。 古いPEARパッケージにはこのエラーが含まれていることが多いので以下のようにエラーが出る箇所を【エラー設定】【エラー戻し】で囲むといいでしょう。
// 【エラー設定】E_STRICT , E_DEPRECATED を非表示
$old_error = error_reporting( E_ALL & ~E_STRICT & ~E_DEPRECATED);
// PEARパッケージの処理(例)
require_once 'XML/Unserializer.php'; // 例:PEARの XML::Unserializer は確実にE_STRICTエラーが出ます。
// 何かしらの処理
// 【エラー戻し】
error_reporting($old_error);
PHPのファイルアップロードのファイル要領制限を変更するには次の3つのパラメーターを調整する必要があります。 (必ずしも3つの値を揃える必要はありません)
upload_max_filesize = 256M
post_max_size = 256M
memory_limit = 256M
upload_max_filesize = 256M
post_max_size = 256M
memory_limit = 256M
# ファイルアップロードの最大サイズを 10Mに設定
php_value upload_max_filesize 10M
php_value post_max_size 10M
# ファイルアップロードの最大サイズを 500Kに設定
php_value upload_max_filesize 500K
php_value post_max_size 500K
// ファイルアップロードの最大サイズを 10M に設定
ini_set('upload_max_filesize', 10 * 1024 * 1024);
print "upload_max_filesize: " . ini_get('upload_max_filesize')." Bytes です。";
とします。
PHPで処理時間の長いプログラムを実行時に 【Maximum execution time of 60 seconds exceeded】(60のところは任意の数字) が出てプログラムが終了する場合があります。
これは60秒以上かかったので強制終了したというエラーです。 どうしても処理が60秒以上かかる場合はタイムアウトまでの時間を変更します。
/etc/php.ini
max_execution_time = 30
max_input_time = 60
の箇所を修正します。
または PHPソース内に
ini_set("max_execution_time",180); // タイムアウトを180秒にセット
ini_set("max_input_time",180); // パース時間を180秒にセット
タイムアウトをさせたくない場合は、PHPソース内に
ini_set("max_execution_time",0); // タイムアウトしない
ini_set("max_input_time",0); // パース時間を設定しない
と設定します。
ちなみにPHPをコマンドライン(CLI)から実行する場合のデフォルト設定は 0 です。
PHPではデフォルトでエラーをログに吐かない。
なので明示的にロギングをするよう設定する。
(PHPスクリプトの最初に記述しておく)
ini_set('log_errors', 1); // エラーをロギングする
毎回記述するのが面倒な場合は
php.ini の該当箇所に記述する。
PHPのエラー表示を設定する箇所は 1: php.ini 2: phpソース内 3: .htaccess の3箇所あります
E_ALL & ~E_NOTICE を記述する場合の例
error_reporting = E_ALL & ~E_NOTICE
error_reporting(E_ALL ^ E_NOTICE);
php_value error_reporting 6135
.htaccess に記述する場合は定数は使えませんので数値で指定します
http://php.net/manual/ja/errorfunc.constants.php
php.ini中の display_errors が Off になっているとエラーが一切表示されなくなります。 エラーがまったく表示されないときはphpソース内に
ini_set( 'display_errors', "1" );
とします。
また phpinfo(); で表示される画面または次のコマンドから php.ini を探し出して php.ini ファイルを書き換えます。
display_errors = Off
↓
display_errors = On
php -r "echo phpinfo();" | grep "php.ini"