PHPプログラムに関する各種メモ書き:タグ「エラー対処」での検索

PHP 7.2 で発生する「 Function create_function() is deprecated」エラーに対処する

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 を使用して渡します。

No.1292
09/05 09:14

edit

エラー対処

IEやEdgeでhistory.back()や「戻る」ボタンで戻った時に消える時の対処法その1

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で確認しましょう。)

そこで 次の方法で対処できます。

● 方法1. php ソースに次の3行を記述する

session_start();

// セッション使用時にブラウザキャッシュを有効にする
header('Expires: -1');
header('Cache-Control:');
header('Pragma:');

記述場所は 「session_start() の後」かつ「何か画面に出力する前」です。

● 方法2.

session_cache_limiter('public'); // セッション使用時にキャッシュを使えるようにする
// ↓PHPのデフォルト値は 180 です
session_cache_expire(60); // セッション時のキャッシュ有効時間 60分(1時間)
session_start();

とすると、セッション使用時にもキャッシュ可能になります。

・session_cache_limiterの引数

session_cache_limiterの引数 説明
none no-cacheヘッダを送信しない
nocache no-cacheヘッダを送信する
private キャッシュを利用する(プロキシサーバーにはキャッシュを利用させない)
private_no_expire キャッシュを利用する(プロキシサーバーにはキャッシュを利用させない)
public キャッシュを利用する

ちなみにセッション自体の有効時間は

ini_set("session.cookie_lifetime", 28800); // セッション有効時間 60*60*8(8時間)

として指定します。

No.680
11/25 00:41

edit

Cookie
セッション
エラー対処

PEAR run-tests を使ったPHPのユニットテスト

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);
}

● テストファイル( .phpt )の作成

テストファイルをディレクトリ 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'$'"

引用 : http://qiita.com/arai-ta/items/450dd84964ad628e287b

No.1123
08/11 08:49

edit

PEAR
エラー対処

php7で変数の型宣言が厳格なコーディングを行う

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

No.1122
04/11 15:15

edit

PHP7
エラー対処

phpcs , phpcbf で phpコードを(チェック / 整形)する

多人数が関わるプロジェクトでは phpコードの書式を統一するのが難しくなります。
そこでプログラマー個人にコーディングルールを覚えさせるよりプログラムで自動判別させます。
下記の phpcs がとても便利です。

● squizlabs/PHP_CodeSniffer ( phpcs )

https://github.com/squizlabs/PHP_CodeSniffer/wiki

1. composer コマンドからインストールします

composer global require "squizlabs/php_codesniffer=*"

2. シェルが bash の場合は次のコマンドでパスを追加しておきます

echo 'export PATH=$HOME/.composer/vendor/bin:$PATH' >> .bash_profile
source .bash_profile

● インストールの確認

phpcs --version

● php ソースコードのチェック (phpcs コマンド)

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 ソースコードの整形 (phpcbf コマンド)

指定したコーディング規約に沿うようphpソースコードを自動で整形してくれます
例)PSR2準拠に自動整形します

phpcbf  --standard=PSR2  [phpファイル名] 
No.1121
04/11 23:22

edit

エラー対処

PHPMD で PHPソースのチェックを行う

● PHPMDとは?

バグにつながりそうな怪しい ソースコードをチェックして教えてくれる php md。
コーディング時に必ず使うようにしておくとミスやバグが減るので是非使いましょう

● PHPMDのインストール

1. composer コマンドからインストールします

composer global require phpmd/phpmd

2. シェルが bash の場合は次のコマンドでパスを追加しておきます

echo 'export PATH=$HOME/.composer/vendor/bin:$PATH' >> .bash_profile
source .bash_profile

3. phpmd コマンドを入力してパスが通ってるか確認します

phpmd --version

● PHPMDで phpソースコードのチェックを行う

(ソースファイル 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

● エディタ SublimeTextで PHPMDを使う

次のパッケージをインストールします

SublimeLinter
SublimeLinter-phpmd

・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ファイルを開いているときに自動的にソースのおかしそうなところを指摘してくれます。

合わせて「SublimeLinter-annotations」もインストールしておきましょう

@todo をハイライト表示してくれるのでとても便利です。

● PHPMDにエラー指摘してほしくない項目をソースコードに直接記述する

PHPMDのエラーを回避したい場合は、ソースコードの クラス名またはメソッドの上に PHPDOC 形式で SuppressWarnings を指定することで エラー表示を回避することが出来ます。 指定できる文字列は (PHPMD.XXXXX) という形式で、XXXXXに指定する文字列はこちらのページから調べることが出来ます。

https://phpmd.org/rules/index.html

例)StaticAccessElseExpression 2つのエラーを表示しないようにします

	/**
	 * @SuppressWarnings(PHPMD.StaticAccess)
	 * @SuppressWarnings(PHPMD.ElseExpression)
	 */
	public function hogehoge( $arg )
	{
		// code ...
	}
No.1120
12/11 09:33

edit

エラー対処
composer

Strict Standards: Only variables should be passed by reference エラーへの対応

PHP5.6以降では配列関係の参照渡しの関数にデータを渡す時は一度変数に入れる必要があります。

● エラーとなる例

$new_array = end( array_keys($array) );

● このように変更します

$ar_key = array_keys($array);
$new_array = end( $ar_key );
No.1089
02/08 18:30

edit

配列
エラー対処

PHP5.6 iconv_set_encoding Deprecated エラーの対処

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'); }
No.1013
09/16 18:23

edit

エラー対処

PHP5.6での【Deprecated: Non-static method】エラーの対応

PHP5.6ではstaticではないメソッドを直接呼び出すとエラーが出ます。

■ 例:PHP5.6では以下のコードはエラーとなる

$config = Spyc::YAMLLoad($yml_filename);

■ 対処法: 以下のようにコードを変更します。

$spyc = new Spyc();
$config = $spyc->YAMLLoad($yml_filename);

参考 : http://bit.ly/1PAKIIC

No.996
01/18 14:45

edit

エラー対処

PHP 5.4のE_STRICTエラーに対応する

PHP 5.4からは 5.3までは出力されなかった【E_STRICTエラー】がデフォルトで出力されるようになっています。 なのでPHPのバージョンを 5.3以下から5.4以上に上げるとE_STRICTエラーが表示されることがよくあります。

1. PHP 5.4のE_STRICTエラーの対処法(ソースを修正する)

自分で書いたソースの場合はエラーの内容を調べて修正するのが一番よいでしょう。
http://goo.gl/moKrOg

2. PHP 5.4のE_STRICTエラーの対処法(エラーを表示しないようにする)

そもそも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);
No.966
07/30 22:40

edit

PEAR
XML
エラー対処

PHPのファイルアップロードのファイル要領制限(upload_max_filesize)を変更する。

PHPのファイルアップロードのファイル要領制限を変更するには次の3つのパラメーターを調整する必要があります。 (必ずしも3つの値を揃える必要はありません)

upload_max_filesize = 256M
post_max_size = 256M
memory_limit = 256M

● 1. php.ini 内に記述する場合

upload_max_filesize = 256M
post_max_size = 256M
memory_limit = 256M

● 2. .htaccess に記述する場合

#  ファイルアップロードの最大サイズを 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

● 3. phpスクリプト内に記述する場合(サーバの設定によっては許可されていない場合があります)

// ファイルアップロードの最大サイズを 10M に設定
ini_set('upload_max_filesize', 10 * 1024 * 1024); 

● なお現在のファイルアップロード制限の設定を取得するには

print "upload_max_filesize: " . ini_get('upload_max_filesize')." Bytes です。";

とします。

No.690
06/03 11:00

edit

ファイル
.htaccess
メモリ
エラー対処

PHPのタイムアウト【Maximum execution time of 60 seconds exceeded】エラーが出る場合の対応

● PHPの Maximum execution time of 60 seconds exceeded エラーの対応

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 です。

No.283
05/31 18:48

edit

エラー対処

エラー、警告メッセージをロギングする。

PHPではデフォルトでエラーをログに吐かない。

なので明示的にロギングをするよう設定する。

(PHPスクリプトの最初に記述しておく)

ini_set('log_errors', 1);					// エラーをロギングする

毎回記述するのが面倒な場合は

php.ini の該当箇所に記述する。


No.243
08/12 10:14

edit

エラー対処

PHPのエラー表示を設定する

PHPのエラー表示を設定する箇所は 1: php.ini 2: phpソース内 3: .htaccess の3箇所あります
E_ALL & ~E_NOTICE を記述する場合の例

● php.ini に記述する場合

error_reporting = E_ALL & ~E_NOTICE

● phpソース内に記述する場合

error_reporting(E_ALL ^ E_NOTICE);

● .htaccessに記述する場合

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.ini の 場所を調べるコマンド

php -r "echo phpinfo();" | grep "php.ini"
No.70
01/10 13:42

edit

エラー対処