参照-このエラーはPHPで何を意味しますか?
これは何ですか?
これは、PHPのプログラミング中に発生する可能性のある警告、エラー、および通知に関する多数の回答であり、それらを修正する方法がわかりません。これもコミュニティWikiであるため、このリストに追加して維持するために、誰でも参加できます。
どうしてこれなの?
「ヘッダーはすでに送信されています」や「非オブジェクトのメンバーに電話をかけています」などの質問は、 StackOverflowで頻繁に表示されます。これらの質問の根本的な原因は常に同じです。したがって、これらの質問への回答は通常、それらを繰り返してから、特定の場合に変更する行をOPに示します。これらの回答は、OPの特定のコードにのみ適用されるため、サイトに何の価値も追加しません。同じエラーを抱えている他のユーザーは、ローカライズされすぎているため、ソリューションを簡単に読み取ることができません。根本的な原因を理解すれば、エラーを修正するのは簡単なので、それは悲しいことです。したがって、このリストは、適用する一般的な方法でソリューションを説明しようとします。
ここで何をすればいいですか?
質問がこれと重複するものとしてマークされている場合は、以下のエラーメッセージを見つけて、修正をコードに適用してください。回答には通常、一般的な回答だけから明確にすべきではない場合に備えて調査するための追加のリンクが含まれています。
貢献したい場合は、「お気に入り」のエラーメッセージ、警告または通知、回答ごとに1つ、その意味の簡単な説明(マニュアルページで用語を強調しているだけの場合でも)、考えられる解決策またはデバッグアプローチを追加してください。価値のある既存のQ&Aのリスト。また、既存の回答を自由に改善してください。
リスト
- 何も見えません。ページは空で白です。(ホワイトページ/スクリーンオブデスとも呼ばれます)
- コードが実行されない/ PHPコードの一部が出力されるように見える
- 警告:ヘッダー情報を変更できません-ヘッダーはすでに送信されています
- 警告:は、mysql_fetch_array()は、リソース、ブール与えられる1パラメータ期待別名
は、mysql_fetch_array():警告与えられた引数が有効なMySQLの結果リソースではない別名
警告:mysqli_num_rows()mysqli_resultことが1パラメータ期待し、ブール所与の(同様の変形又は) - 警告:[関数]はパラメーター1がリソースであると想定しており、ブール値が指定されています
- 警告:[機能]:ストリームを開くことができませんでした:[理由]
- 警告:open_basedir制限が有効です
- 警告:ゼロ除算
- 警告:不正な文字列オフセット 'XXX'
- 警告:count():パラメータはCountableを実装する配列またはオブジェクトである必要があります
- 解析エラー:構文エラー、予期しない '['
- 解析エラー:構文エラー、予期しないT_XXX
- 解析エラー:構文エラー、予期しないT_ENCAPSED_AND_WHITESPACE
- 解析エラー:構文エラー、予期しないT_PAAMAYIM_NEKUDOTAYIM
- 解析エラー:構文エラー、予期しない 'require_once'(T_REQUIRE_ONCE)、関数(T_FUNCTION)が必要です
- 解析エラー:構文エラー、予期しないT_VARIABLE
- 致命的なエラー:許可されたXXXバイトのメモリサイズが使い果たされました(XXXバイトを割り当てようとしました)
- 致命的なエラー:非オブジェクトまたはnullでのメンバー関数の呼び出し
- 致命的なエラー:未定義の関数XXXの呼び出し
- 致命的なエラー:XXXを再宣言できません
- 致命的なエラー:書き込みコンテキストで関数の戻り値を使用できません
- 致命的なエラー:AAA :: BBB()の宣言はCCC :: BBB()の宣言と互換性がある必要があります'
- 致命的なエラー:オブジェクトコンテキストにないときに$ thisを使用する
- 致命的なエラー:クラスClosureのオブジェクトを文字列に変換できませんでした
- 致命的なエラー:未定義のクラス定数
- 注意:配列から文字列への変換
- 注意:非オブジェクトエラーのプロパティを取得しようとしています
- 注意:未定義の変数またはプロパティ
- 注意:未定義のインデックス
- 注意:未定義のオフセットXXX [参照]
- 注意:初期化されていない文字列オフセット:XXX
- 注意:未定義の定数XXXの使用-「XXX」と見なされます
- MySQL:SQL構文にエラーがあります。近くで使用する正しい構文については、MySQLサーバーのバージョンに対応するマニュアルを確認してください...行...
- 厳格な基準:非静的メソッド[<class> :: <method>]は静的に呼び出されるべきではありません
- 警告:関数はパラメータXがブール/文字列/整数であることを期待しています
- HTTPエラー500-内部サーバーエラー
- 非推奨:中括弧を使用した配列と文字列のオフセットアクセス構文は非推奨になりました
また、以下を参照してください。
回答
警告:ヘッダー情報を変更できません-ヘッダーはすでに送信されています
スクリプトがHTTPヘッダーをクライアントに送信しようとしたが、以前に出力がすでに行われていたために、ヘッダーがクライアントに送信された場合に発生します。
これはでE_WARNING
あり、スクリプトを停止しません。
典型的な例は、次のようなテンプレートファイルです。
<html>
<?php session_start(); ?>
<head><title>My Page</title>
</html>
...
このsession_start()
関数は、セッションCookieを含むヘッダーをクライアントに送信しようとします。しかし、PHPは<html>
要素を出力ストリームに書き込んだときに、すでにヘッダーを送信しています。を上に移動するsession_start()
必要があります。
警告をトリガーするコードの前の行を調べて、出力される場所を確認することで、これを解決できます。ヘッダー送信コードをそのコードの前に移動します。
見落とされがちな出力は、PHPの終了後の新しい行?>
です。それが?>
ファイルの最後のものである場合は省略するのが標準的な方法と考えられています。同様に、この警告のもう1つの一般的な原因は、開口部の<?php
前に空のスペース、行、または非表示の文字があり、Webサーバーがヘッダーと空白/改行を送信するため、PHPが解析を開始すると送信できなくなることです。任意のヘッダー。
ファイルに複数の<?php ... ?>
コードブロックが含まれている場合は、それらの間にスペースを入れないでください。(注:自動的に作成されたコードがある場合は、複数のブロックが存在する可能性があります)
また、コードにバイトオーダーマークが含まれていないことを確認してください。たとえば、スクリプトのエンコーディングがBOMを使用したUTF-8の場合などです。
関連する質問:
致命的なエラー:非オブジェクトでのメンバー関数の呼び出し...
がオブジェクトxyz->method()
でxyz
はないため、method
呼び出すことができない場所と同様のコードで発生します。
これは致命的なエラーであり、スクリプトが停止します(上位互換性の通知:PHP 7以降はキャッチ可能なエラーになります)。
ほとんどの場合、これはコードにエラー状態のチェックがないことを示しています。メソッドを呼び出す前に、オブジェクトが実際にオブジェクトであることを確認してください。
典型的な例は次のようになり
// ... some code using PDO
$statement = $pdo->prepare('invalid query', ...);
$statement->execute(...);
上記の例では、クエリを準備できず、prepare()
に割り当てfalse
られ$statement
ます。execute()
メソッドを呼び出そうとすると、false
値がブール値であるため、は「非オブジェクト」であるため、致命的なエラーが発生します。
把握、なぜあなたの関数ではなく、オブジェクトのブール値を戻しました。たとえば$pdo
、最後に発生したエラーがないかオブジェクトを確認します。これをデバッグする方法の詳細は、問題の特定の関数/オブジェクト/クラスのエラーがどのように処理されるかによって異なります。
->prepare
が失敗している場合でも、$pdo
データベースハンドルオブジェクトは現在のスコープに渡されませんでした。それが定義された場所を見つけます。次に、それをパラメーターとして渡すか、プロパティとして保存するか、グローバルスコープを介して共有します。
別の問題は、条件付きでオブジェクトを作成してから、その条件付きブロックの外部でメソッドを呼び出そうとすることです。例えば
if ($someCondition) {
$myObj = new MyObj();
}
// ...
$myObj->someMethod();
条件付きブロックの外部でメソッドを実行しようとすると、オブジェクトが定義されない場合があります。
関連する質問:
何も見えません。ページは空で白です。
White Page OfDeathまたはWhiteScreen OfDeathとしても知られています。これは、エラーレポートがオフになっていて、致命的なエラー(多くの場合構文エラー)が発生した場合に発生します。
エラーログを有効にしている場合は、エラーログに具体的なエラーメッセージが表示されます。これは通常、「php_errors.log」というファイルにあり、中央の場所(/var/log/apache2
多くのLinux環境など)またはスクリプト自体のディレクトリ(共有ホスティング環境で使用されることもあります)にあります。
エラーの表示を一時的に有効にする方が簡単な場合があります。ホワイトページにエラーメッセージが表示されます。これらのエラーはWebサイトにアクセスするすべての人に表示されるため、注意してください。
これは、スクリプトの先頭に次のPHPコードを追加することで簡単に実行できます。
ini_set('display_errors', 1); error_reporting(~0);
コードはエラーの表示をオンにし、レポートを最高レベルに設定します。
ini_set()
は実行時に実行されるため、解析/構文エラーには影響しません。これらのエラーはログに表示されます。それらを出力にも(たとえばブラウザで)表示したい場合は、display_startup_errors
ディレクティブをに設定する必要がありますtrue
。これは、php.ini
またはで、.htaccess
または実行前の構成に影響を与えるその他の方法で行います。
同じ方法を使用してlog_errorsおよびerror_logディレクティブを設定し、独自のログファイルの場所を選択できます。
ログを確認するか、ディスプレイを使用すると、はるかに優れたエラーメッセージと、スクリプトが停止するコード行が表示されます。
関連する質問:
- PHPの死の白い画面
- 死の白い画面!
- PHPはエラーメッセージを表示しません
- エラーで500を放出するPHP-これはどこに文書化されていますか?
- PHPで有用なエラーメッセージを取得するにはどうすればよいですか?
- Stackoverflowに関するすべてのPHP「WhitePageofDeath」の質問
関連エラー:
注意:未定義のインデックス
配列に存在しないキーで配列にアクセスしようとすると発生します。
Undefined Index
通知の典型的な例は(デモ)です
$data = array('foo' => '42', 'bar');
echo $data['spinach'];
echo $data[1];
両方spinach
と1
引き起こし、アレイ内に存在しないE_NOTICE
トリガーします。
解決策は、そのインデックスにアクセスする前に、インデックスまたはオフセットが存在することを確認することです。これは、プログラムのバグを修正して、それらのインデックスが期待どおりに存在することを確認する必要があることを意味する場合があります。それとも、インデックスが使用して存在するかどうかをテストする必要があることを意味しますarray_key_exists
かisset
:
$data = array('foo' => '42', 'bar');
if (array_key_exists('spinach', $data)) {
echo $data['spinach'];
}
else {
echo 'No key spinach in the array';
}
次のようなコードがある場合:
<?php echo $_POST['message']; ?>
<form method="post" action="">
<input type="text" name="message">
...
その後、$_POST['message']
このページが最初にロードされたときに設定されることはありません、あなたは上記のエラーを取得します。フォームが送信され、このコードが2回実行された場合にのみ、配列インデックスが存在します。通常、これは次の方法で確認します。
if ($_POST) .. // if the $_POST array is not empty
// or
if ($_SERVER['REQUEST_METHOD'] == 'POST') .. // page was requested with POST
関連する質問:
警告:mysql_fetch_array()は、パラメーター1がリソースであると想定しており、ブール値が指定されています
何よりもまず:
mysql_*
新しいコードで関数を使用しないでください。それらはもはや維持されておらず、公式に非推奨になっています。参照してください赤いボックスを?代わりにプリペアドステートメントについて学び、 PDOまたはMySQLiを使用してください-この記事はどちらを決定するのに役立ちます。PDOを選択した場合は、ここに優れたチュートリアルがあります。
これは、の結果からデータをフェッチしようとしたmysql_query
が、クエリが失敗した場合に発生します。
これは警告であり、スクリプトを停止することはありませんが、プログラムが間違ったものになります。
あなたは、によって返された結果をチェックする必要があるmysql_query
ことでを
$res = mysql_query($sql);
if (!$res) {
die(mysql_error());
}
// after checking, do the fetch
関連する質問:
- mysql_fetch_array()は、パラメーター1がリソースであり、ブール値がselectで指定されていることを想定しています。
- すべての「mysql_fetch_array()はパラメータ1がリソースであり、ブール値が与えられていることを期待しています」Stackoverflowに関する質問
関連エラー:
mysql*
MySQL結果リソースをパラメーターとして期待する他の関数も同じ理由で同じエラーを生成します。
致命的なエラー:オブジェクトコンテキストにないときに$ thisを使用する
$this
割り当てることができないPHPの特別な変数です。それが存在しないコンテキストでアクセスされた場合、この致命的なエラーが発生します。
このエラーが発生する可能性があります。
非静的メソッドが静的に呼び出された場合。例:
class Foo { protected $var; public function __construct($var) { $this->var = $var; } public static function bar () { // ^^^^^^ echo $this->var; // ^^^^^ } } Foo::bar();
修正方法:コードを再確認します。
$this
オブジェクトコンテキストでのみ使用でき、静的メソッドでは使用しないでください。また、静的メソッドは非静的プロパティにアクセスしないでください。self::$static_property
静的プロパティにアクセスするために使用します。クラスメソッドのコードが通常の関数またはグローバルスコープにコピーされ、特別な変数を保持している
$this
場合。
修正方法:コードを確認$this
し、別の置換変数に置き換えます。
関連する質問:
致命的なエラー:未定義の関数XXXの呼び出し
まだ定義されていない関数を呼び出そうとすると発生します。一般的な原因には、拡張機能とインクルードの欠落、条件付き関数宣言、関数宣言内の関数、または単純なタイプミスが含まれます。
例1-条件関数宣言
$someCondition = false;
if ($someCondition === true) {
function fn() {
return 1;
}
}
echo fn(); // triggers error
この場合、fn()
は$someCondition
真ではないため、宣言されることはありません。
例2-関数宣言の関数
function createFn()
{
function fn() {
return 1;
}
}
echo fn(); // triggers error
この場合、が呼び出されるとfn
宣言さcreateFn()
れます。以降の呼び出しcreateFn()
では、既存の関数の再宣言に関するエラーがトリガーされることに注意してください。
これは、PHPの組み込み関数でも見られる場合があります。公式マニュアルで関数を検索し、それが属する「拡張機能」(PHPモジュール)と、それをサポートするPHPのバージョンを確認してください。
拡張機能がない場合は、その拡張機能をインストールして、php.iniで有効にします。関数が表示される拡張機能については、PHPマニュアルのインストール手順を参照してください。パッケージマネージャー(apt
DebianまたはUbuntu、yum
Red HatまたはCentOSなど)またはコントロールパネルを使用して拡張機能を有効またはインストールできる場合もあります。共有ホスティング環境で。
関数が使用しているものから新しいバージョンのPHPで導入された場合は、マニュアルまたはそのコメントセクションに代替実装へのリンクがあります。PHPから削除されている場合は、不要になった可能性があるため、理由に関する情報を探してください。
インクルードが欠落している場合は、関数を呼び出す前に、関数を宣言するファイルを必ずインクルードしてください。
タイプミスの場合は、タイプミスを修正してください。
関連する質問:
解析エラー:構文エラー、予期しないT_XXX
予期しない場所にT_XXX
トークンがある場合、不均衡な(不要な)括弧、php.iniでアクティブ化せずに短いタグを使用する場合などに発生します。
関連する質問:
- 参照:PHP解析/構文エラー; とそれらを解決する方法は?
- 解析エラー:構文エラー:予期しない '{'
- 解析エラー:構文エラー、PHPコードの予期しないファイルの終わり
- 解析エラー:構文エラー、予期しない「<」-修正?
- 解析エラー:構文エラー、予期しない '?'
さらにヘルプが必要な場合は、以下を参照してください。
- http://phpcodechecker.com/-これは、構文の問題についてさらに役立つ説明を提供します。
致命的なエラー:書き込みコンテキストで関数の戻り値を使用できません
これは通常、関数をで直接使用する場合に発生しempty
ます。
例:
if (empty(is_null(null))) {
echo 'empty';
}
これは、empty
が関数ではなく言語構造であるため、5.5より前のPHPバージョンでは、引数として式を使用して呼び出すことはできません。PHP 5.5より前のバージョンでは、引数empty()
は変数である必要がありますが、PHP 5.5以降では任意の式(関数の戻り値など)を使用できます。
empty
は、その名前にもかかわらず、変数が「空」であるかどうかを実際にはチェックしません。代わりに、変数が存在しないかどうか、またはをチェックします== false
。式(is_null(null)
例のように)は常に存在すると見なされるため、ここでempty
はそれがfalseに等しいかどうかのみをチェックしています。empty()
ここで!
、たとえばif (!is_null(null))
、に置き換えるか、明示的にfalseと比較することができif (is_null(null) == false)
ます。
関連する質問:
MySQL:SQL構文にエラーがあります。近くで使用する正しい構文については、MySQLサーバーのバージョンに対応するマニュアルを確認してください...行...
このエラーは、MySQLクエリに渡されたデータを適切にエスケープするのを忘れたためによく発生します。
してはいけないことの例(「悪い考え」):
$query = "UPDATE `posts` SET my_text='{$_POST['text']}' WHERE id={$_GET['id']}";
mysqli_query($db, $query);
このコードは、http://example.com/edit.php?id = 10(投稿番号10を編集するため)などのURLを使用して、送信するフォームのあるページに含めることができます。
送信されたテキストに一重引用符が含まれている場合はどうなりますか?$query
最終的に:
$query = "UPDATE `posts` SET my_text='I'm a PHP newbie' WHERE id=10';
そして、このクエリがMySQLに送信されると、途中に余分な一重引用符があるため、構文が間違っていると文句を言います。
このようなエラーを回避するには、しなければならない、常にクエリで使用する前にデータをエスケープ。
SQLクエリで使用する前にデータをエスケープすることも非常に重要です。エスケープしないと、スクリプトがSQLインジェクションに対して開かれるためです。SQLインジェクションは、レコード、テーブル、またはデータベース全体の変更、損失、または変更を引き起こす可能性があります。これは非常に深刻なセキュリティの問題です。
ドキュメンテーション:
解析エラー:構文エラー、予期しないT_ENCAPSED_AND_WHITESPACE
このエラーは、複素変数構造全体がで囲まれていない場合に、二重引用符で囲まれた文字列内の補間のために引用符で囲まれたキーを使用して配列値を参照しようとしたときに最もよく発生し{}
ます。
エラーの場合:
これにより、Unexpected T_ENCAPSED_AND_WHITESPACE
次のようになります。
echo "This is a double-quoted string with a quoted array key in $array['key']";
//---------------------------------------------------------------------^^^^^
考えられる修正:
二重引用符で囲まれた文字列では、PHPは配列キー文字列を引用符なしで使用することを許可し、を発行しませんE_NOTICE
。したがって、上記は次のように書くことができます。
echo "This is a double-quoted string with an un-quoted array key in $array[key]";
//------------------------------------------------------------------------^^^^^
複雑な配列変数とキー全体をで囲むことができます。{}
その場合、を避けるために引用符で囲む必要がありE_NOTICE
ます。 PHPのドキュメントでは、複雑な変数に対してこの構文を推奨しています。
echo "This is a double-quoted string with a quoted array key in {$array['key']}";
//--------------------------------------------------------------^^^^^^^^^^^^^^^
// Or a complex array property of an object:
echo "This is a a double-quoted string with a complex {$object->property->array['key']}";
もちろん、上記のいずれかの代替手段は、配列変数を補間するのではなく、連結することです。
echo "This is a double-quoted string with an array variable". $array['key'] . " concatenated inside.";
//----------------------------------------------------------^^^^^^^^^^^^^^^^^^^^^
参考までに、PHP文字列のマニュアルページの変数解析に関するセクションを参照してください。
致命的なエラー:許可されたXXXバイトのメモリサイズが使い果たされました(XXXバイトを割り当てようとしました)
スクリプトを実行するのに十分なメモリがありません。PHPがメモリ制限に達し、実行を停止します。このエラーは致命的であり、スクリプトは停止します。メモリ制限の値は、php.ini
ファイル内で、またはini_set('memory_limit', '128 M');
スクリプトで使用して構成できます(で定義された値を上書きしますphp.ini
)。メモリ制限の目的は、単一のPHPスクリプトが使用可能なすべてのメモリを使い果たしてWebサーバー全体をダウンさせないようにすることです。
最初に行うことは、スクリプトに必要なメモリの量を最小限に抑えることです。たとえば、大きなファイルを変数に読み込んだり、データベースから多くのレコードをフェッチしてそれらをすべて配列に格納したりすると、大量のメモリを使用する可能性があります。コードを変更して、代わりにファイルを1行ずつ読み取るか、データベースレコードをすべてメモリに保存せずに一度に1つずつフェッチします。これには、舞台裏で何が起こっているのか、データがいつメモリに保存されるのか、他の場所に保存されるのかについて、少し概念的な認識が必要です。
スクリプトがメモリを大量に消費する作業を行っていないときにこのエラーが発生した場合は、コードをチェックしてメモリリークがないかどうかを確認する必要があります。memory_get_usage
機能はあなたの友達です。
関連する質問:
警告:[機能]:ストリームを開くことができませんでした:[理由]
あなたが通常でファイルを呼び出すときに起こるinclude
、require
またはfopen
とPHPはファイルを見つけるか、ファイルをロードするために十分ではない権限を持っていませんでした。
これはさまざまな理由で発生する可能性があります。
- ファイルパスが間違っています
- ファイルパスは相対的です
- インクルードパスが間違っている
- 権限が制限されすぎています
- SELinuxが有効です
- などなど ...
よくある間違いの1つは、絶対パスを使用しないことです。これは、簡単に完全なパスまたは使用することによって解決することができる魔法の定数のように__DIR__
か dirname(__FILE__)
。
include __DIR__ . '/inc/globals.inc.php';
または:
require dirname(__FILE__) . '/inc/globals.inc.php';
正しいパスが使用されていることを確認することは、これらの問題のトラブルシューティングの1つのステップです。これは、存在しないファイル、アクセスを妨げるファイルシステムの権限、またはPHP自体によるオープンベースの制限に関連している可能性もあります。
この問題をすばやく解決する最善の方法は、以下のトラブルシューティングチェックリストに従うことです。
関連する質問:
関連エラー:
解析エラー:構文エラー、予期しないT_PAAMAYIM_NEKUDOTAYIM
スコープ解決演算子は、ヘブライ語のפעמייםנקודתייםから「PaamayimNekudotayim」とも呼ばれます。これは「ダブルコロン」を意味します。
このエラーは通常、誤っ::
てコードを入力した場合に発生します。
関連する質問:
- 参照:PHP解析/構文エラー; とそれらを解決する方法は?
- PHPで2つのコロンはどういう意味ですか?
- PHPの::(二重コロン)と->(矢印)の違いは何ですか?
- 予期しないT_PAAMAYIM_NEKUDOTAYIM、T_NS_Separatorを期待
ドキュメンテーション:
注意:未定義の定数XXXの使用-「XXX」と見なされます
または、PHP 7.2以降の場合:
警告:未定義の定数XXXの使用-「XXX」と見なされます(これにより、PHPの将来のバージョンでエラーがスローされます)
この通知は、トークンがコードで使用され、定数のように見えるが、その名前の定数が定義されていない場合に発生します。
この通知の最も一般的な原因の1つは、連想配列キーとして使用される文字列を引用できないことです。
例えば:
// Wrong
echo $array[key];
// Right
echo $array['key'];
もう1つの一般的な原因は$
、変数名の前に(ドル)記号がないことです。
// Wrong
echo varName;
// Right
echo $varName;
または、他の定数またはキーワードのスペルを間違えた可能性があります。
// Wrong
$foo = fasle;
// Right
$foo = false;
また、そのライブラリによって定義された定数にアクセスしようとしたときに、必要なPHP拡張機能またはライブラリが欠落していることを示している可能性もあります。
関連する質問:
致命的なエラー:クラス[クラス名]を再宣言できません
致命的なエラー:[関数名]を再宣言できません
この手段どちらか二度同じ機能/クラス名を使用して、そのうちの1の名前を変更する必要がある、またはあなたが使用しているので、それはしているrequire
か、include
あなたが使用する必要がありますどこrequire_once
かinclude_once
。
クラスまたは関数がPHPで宣言されている場合、それは不変であり、後で新しい値で宣言することはできません。
次のコードについて考えてみます。
class.php
<?php
class MyClass
{
public function doSomething()
{
// do stuff here
}
}
index.php
<?php
function do_stuff()
{
require 'class.php';
$obj = new MyClass;
$obj->doSomething();
}
do_stuff();
do_stuff();
を2回呼び出すとdo_stuff()
、上記のエラーが発生します。に変更require
するrequire_once
ことで、の定義を含むファイルがMyClass
1回だけ読み込まれ、エラーが回避されることを確認できます。
注意:未定義の変数
以前に定義されていない変数を使用しようとすると発生します。
典型的な例は
foreach ($items as $item) {
// do something with item
$counter++;
}
$counter
以前に定義しなかった場合は、上記のコードが通知をトリガーします。
正しい方法は、変数が次のような単なる空の文字列であっても、使用する前に変数を設定することです。
$counter = 0;
foreach ($items as $item) {
// do something with item
$counter++;
}
同様に、無名関数を使用する場合など、変数はそのスコープ外ではアクセスできません。
$prefix = "Blueberry";
$food = ["cake", "cheese", "pie"];
$prefixedFood = array_map(function ($food) {
// Prefix is undefined
return "${prefix} ${food}";
}, $food);
代わりに、これを使用して渡す必要があります use
$prefix = "Blueberry";
$food = ["cake", "cheese", "pie"];
$prefixedFood = array_map(function ($food) use ($prefix) {
return "${prefix} ${food}";
}, $food);
注意:未定義のプロパティ
このエラーはほとんど同じことを意味しますが、オブジェクトのプロパティを参照しています。上記の例を再利用すると、counter
プロパティが設定されていないため、このコードはエラーをトリガーします。
$obj = new stdclass;
$obj->property = 2342;
foreach ($items as $item) {
// do something with item
$obj->counter++;
}
関連する質問:
解析エラー:構文エラー、予期しないT_VARIABLE
考えられるシナリオ
コードがどこで間違っているのかわからないようです。これが私の完全なエラーです:
解析エラー:構文エラー、行xに予期しないT_VARIABLE
私が試していること
$sql = 'SELECT * FROM dealer WHERE id="'$id.'"';
回答
解析エラー:ステートメントの終わりからセミコロンを外したり、上記の場合のように.
演算子が欠落しているなど、プログラムの構文に問題があります。インタープリターは、解析エラーが発生するとプログラムの実行を停止します。
簡単に言うと、これは構文エラーです。つまり、コードに何かがあり、コードが正しく解析されて実行されないようになっています。
あなたがすべきことは、エラーがどこにあるかという周りの行で、単純な間違いがないか注意深くチェックすることです。
このエラーメッセージは、ファイルのx行で、PHPインタープリターが開き括弧が表示されることを期待していましたが、代わりに、と呼ばれるものが検出されたことを意味しますT_VARIABLE
。それT_VARIABLE
はと呼ばれますtoken
。これは、プログラムのさまざまな基本部分を表現するPHPインタープリターの方法です。インタプリタがプログラムを読み込むと、書き込んだ内容がトークンのリストに変換されます。プログラムのどこに変数を置いてもT_VARIABLE
、インタプリタのリストにはトークンがあります。
したがって、少なくともE_PARSE
で有効にするようにしてくださいphp.ini
。解析エラーは本番スクリプトに存在してはなりません。
コーディング中は、常に次のステートメントを追加することをお勧めします。
error_reporting(E_ALL);
また、入力中に解析エラーを通知するIDEを使用することをお勧めします。次を使用できます。
- NetBeans(すばらしい美しさ、フリーソフトウェア)(私の意見では最高)
- PhpStorm(Gordonおじさんはこれが大好きです:P、有料プラン、プロプライエタリソフトウェアとフリーソフトウェアが含まれています)
- Eclipse(美女と野獣、フリーソフトウェア)
関連する質問:
注意:初期化されていない文字列オフセット: *
名前が示すように、このようなタイプのエラーは、存在しないキーを使用して配列から値を反復または検索しようとしている可能性が高い場合に発生します。
あなたを考慮して、からのすべての手紙を見せようとしています $string
$string = 'ABCD';
for ($i=0, $len = strlen($string); $i <= $len; $i++){
echo "$string[$i] \n";
}
A
B
C
D
Notice: Uninitialized string offset: 4 in XXX on line X
また、スクリプトがエコーD
を終了するとすぐにエラーが発生します。これは、for()
ループ'ABCD'
内で、存在する最初から5番目の文字列を表示するようにPHPに指示したためですが、ループがカウントを開始して0
エコーするためです。D
に達するまで4
に、オフセットエラーがスローされます。
同様のエラー:
注意:非オブジェクトエラーのプロパティを取得しようとしています
オブジェクトがないときにオブジェクトのプロパティにアクセスしようとすると発生します。
オブジェクト以外の通知の典型的な例は次のとおりです。
$users = json_decode('[{"name": "hakre"}]');
echo $users->name; # Notice: Trying to get property of non-object
この場合、$users
は配列(オブジェクトではない)であり、プロパティはありません。
これは、配列の存在しないインデックスまたはキーにアクセスするのと似ています(注意:未定義のインデックスを参照)。
この例は非常に単純化されています。ほとんどの場合、このような通知は、チェックされていない戻り値を示します。たとえばNULL
、オブジェクトが存在しない場合や予期しない非オブジェクト値(Xpathの結果、予期しない形式のJSON構造、予期しない形式のXMLなど)でライブラリが返される場合などです。しかし、コードはそのような状態をチェックしません。
これらの非オブジェクトはさらに処理されることが多いため、非オブジェクトでオブジェクトメソッドを呼び出すと、次に致命的なエラーが発生することがよくあります(致命的なエラー:非オブジェクトでのメンバー関数の呼び出し...を参照)。脚本。
エラー状態をチェックしたり、変数が期待値と一致したりすることで、簡単に防ぐことができます。ここに、DOMXPathの例を含むそのような通知があります。
$result = $xpath->query("//*[@id='detail-sections']/div[1]");
$divText = $result->item(0)->nodeValue; # Notice: Trying to get property of non-object
問題はnodeValue
、最初のアイテムが$result
コレクションに存在するかどうかがチェックされていないときに、そのプロパティ(フィールド)にアクセスすることです。代わりに、コードが操作するオブジェクトに変数を割り当てることで、コードをより明確にすることが重要です。
$result = $xpath->query("//*[@id='detail-sections']/div[1]");
$div = $result->item(0);
$divText = "-/-";
if (is_object($div)) {
$divText = $div->nodeValue;
}
echo $divText;
関連エラー:
警告:open_basedir制限が有効です
この警告は、ファイルおよびディレクトリへのアクセスに関連するさまざまな機能で発生する可能性があります。構成の問題について警告します。
表示されている場合は、一部のファイルへのアクセスが禁止されていることを意味します。
警告自体は何も壊しませんが、ファイルアクセスが妨げられていると、ほとんどの場合、スクリプトは正しく機能しません。
修正は通常、PHP構成を変更することであり、関連する設定はと呼ばれopen_basedir
ます。
間違ったファイル名またはディレクトリ名が使用されることがありますが、修正は正しいものを使用することです。
関連する質問:
解析エラー:構文エラー、予期しない '['
このエラーには、次の2つの変種があります。
バリエーション1
$arr = [1, 2, 3];
この配列初期化構文は、PHP5.4でのみ導入されました。それより前のバージョンではパーサーエラーが発生します。可能であれば、インストールをアップグレードするか、古い構文を使用してください。
$arr = array(1, 2, 3);
マニュアルのこの例も参照してください。
バリエーション2
$suffix = explode(',', 'foo,bar')[1];
配列逆参照関数の結果もPHP5.4で導入されました。アップグレードできない場合は、(一時)変数を使用する必要があります。
$parts = explode(',', 'foo,bar');
$suffix = $parts[1];
マニュアルのこの例も参照してください。
警告:[関数]はパラメーター1がリソースであると想定しており、ブール値が指定されています
(警告のより一般的なバリエーション:mysql_fetch_array()は、パラメーター1がリソースであり、ブール値が指定されていることを想定しています)
リソースはPHPのタイプです(文字列、整数、オブジェクトなど)。リソースは不透明なブロブであり、本質的に意味のある独自の値はありません。リソースは、特定のPHP関数または拡張機能のセットに固有であり、それらによって定義されます。たとえば、Mysql拡張機能は2つのリソースタイプを定義します。
MySQLモジュールで使用されるリソースタイプは2つあります。1つ目はデータベース接続のリンク識別子で、2つ目はクエリの結果を保持するリソースです。
cURL拡張機能は、別の2つのリソースタイプを定義します。
... cURLハンドルとcURLマルチハンドル。
ときvar_dump
編、値は次のようになります。
$resource = curl_init();
var_dump($resource);
resource(1) of type (curl)
ほとんどのリソースは、(1)
特定のタイプ((curl)
)の数値識別子()です。
これらのリソースを持ち運び、そのようなリソースが何かを意味するさまざまな関数に渡します。通常、これらの関数は特定のデータをバックグラウンドで割り当て、リソースはこのデータを内部で追跡するために使用する単なる参照です。
「...はパラメータ1がリソースであると想定し、ブール値が与えられた」エラーは通常、リソースを作成するはずだったが、false
代わりに返される未チェックの操作の結果です。たとえば、fopen
関数には次の説明があります。
戻り値
成功または
FALSE
エラー時にファイルポインタリソースを返します。
だから、このコードでは、$fp
どちらかになりますresource(x) of type (stream)
かfalse
。
$fp = fopen(...);
fopen
操作が成功したか失敗したか、したがって$fp
有効なリソースであるかどうか、またはリソースを期待する別の関数にfalse
渡すかどうかを確認しないと$fp
、上記のエラーが発生する可能性があります。
$fp = fopen(...);
$data = fread($fp, 1024);
Warning: fread() expects parameter 1 to be resource, boolean given
リソースを割り当てようとして失敗する可能性のある関数の戻り値を常にエラーチェックする必要があります。
$fp = fopen(...);
if (!$fp) {
trigger_error('Failed to allocate resource');
exit;
}
$data = fread($fp, 1024);
関連エラー:
警告:不正な文字列オフセット 'XXX'
これは、角括弧構文を使用して配列要素にアクセスしようとしたときに発生しますが、配列ではなく文字列に対してこれを行っているため、操作は明らかに意味がありません。
例:
$var = "test";
echo $var["a_key"];
変数が配列である必要があると思われる場合は、それがどこから来ているかを確認し、そこで問題を修正してください。
コードが実行されない/ PHPコードの一部が出力されるように見える
PHPコードの結果がまったく表示されない場合、および/またはWebページにリテラルのPHPソースコード出力の一部が表示される場合は、PHPが実際に実行されていないことを確認できます。ブラウザで[ソースの表示]を使用している場合は、PHPソースコードファイル全体がそのまま表示されている可能性があります。PHPコードは<?php ?>
タグに埋め込まれているため、ブラウザはそれらをHTMLタグとして解釈しようとし、結果が多少混乱する可能性があります。
PHPスクリプトを実際に実行するには、次のものが必要です。
- スクリプトを実行するWebサーバー
- ファイル拡張子を.phpに設定します。そうしないと、Webサーバーはそれをそのように解釈しません*
- Webサーバー経由で.phpファイルにアクセスするには
*再構成しない限り、すべてを構成できます。
この最後のものは特に重要です。ファイルをダブルクリックするだけで、次のようなアドレスを使用してブラウザで開く可能性があります。
file://C:/path/to/my/file.php
これは、実行している可能性のあるWebサーバーを完全にバイパスしており、ファイルは解釈されません。Webサーバー上のファイルのURLにアクセスする必要があります。おそらく次のようなものです。
http://localhost/my/file.php
<?
代わりに短いオープンタグを使用していて<?php
、PHP構成で短いオープンタグがオフになっているかどうかを確認することもできます。
注意:配列から文字列への変換
これは、配列を文字列として処理しようとした場合に発生します。
$arr = array('foo', 'bar');
echo $arr; // Notice: Array to string conversion
$str = 'Something, ' . $arr; // Notice: Array to string conversion
echo
結果が明確に定義されていないため、配列を単純に'dしたり、文字列と連結したりすることはできません。PHPは、配列の代わりに文字列「Array」を使用し、通知をトリガーして、それがおそらく意図されたものではなく、ここでコードをチェックする必要があることを指摘します。代わりに、おそらく次のようなものが必要です。
echo $arr[0]; // displays foo
$str = 'Something ' . join(', ', $arr); //displays Something, foo, bar
または、配列をループします。
foreach($arr as $key => $value) {
echo "array $key = $value";
// displays first: array 0 = foo
// displays next: array 1 = bar
}
この通知が予期しない場所に表示される場合は、文字列と思われる変数が実際には配列であることを意味します。これは、コードにバグがあり、この変数が期待する文字列ではなく配列になることを意味します。
警告:mysql_connect():ユーザー 'name' @ 'host'のアクセスが拒否されました
この警告は、資格情報(ユーザー名/パスワード)が無効または欠落しているMySQL / MariaDBサーバーに接続したときに表示されます。だから、これは一般的にあるではないコードの問題が、サーバー構成の問題。
mysql_connect("localhost", "user", "pw")
例については、のマニュアルページを参照してください。あなたが実際に使用されていることを確認
$username
して$password
。- パスワードなしでアクセスできることはめったにありません。これは、警告:が言ったときに起こったこと
(using password: NO)
です。 通常、ローカルテストサーバーのみがユーザー名
root
、パスワードなし、およびtest
データベース名での接続を許可します。コマンドラインクライアントを使用して、それらが本当に正しいかどうかをテストできます。
mysql --user="username" --password="password" testdb
ユーザー名とパスワードでは大文字と小文字が区別され、空白は無視されません。パスワードにのようなメタ文字が含まれている場合は、
$
それらをエスケープするか、パスワードを一重引用符で囲んでください。ほとんどの共有ホスティングプロバイダーは、unixユーザーアカウントに関連してmysqlアカウントを事前に宣言しています(プレフィックスまたは追加の数値サフィックスのみの場合もあります)。パターンやドキュメントについてはドキュメントを、パスワードを設定するためのCPanelやその他のインターフェースを参照してください。
コマンドラインを使用したユーザーアカウントの追加に関するMySQLのマニュアルを参照してください。管理者ユーザーとして接続すると、次のようなクエリを発行できます。
CREATE USER 'username'@'localhost' IDENTIFIED BY 'newpassword';
または、Adminer、WorkBench、またはその他のグラフィカルツールを使用して、アカウントの詳細を作成、確認、または修正します。
資格情報を修正できない場合は、インターネットに「助けてください」と言っても効果がありません。あなたとあなたのホスティングプロバイダーだけが、物事を診断して修正するための許可と十分なアクセス権を持っています。
- パスワードなしでアクセスできることはめったにありません。これは、警告:が言ったときに起こったこと
プロバイダーから指定されたホスト名を使用して、データベースサーバーにアクセスできることを確認します。
ping dbserver.hoster.example.net
これは、Webサーバー上のSSHコンソールから直接確認してください。ローカル開発クライアントから共有ホスティングサーバーへのテストが意味を持つことはめったにありません。
多くの場合、サーバー名をにしたいだけです
"localhost"
。これは通常、使用可能な場合はローカルの名前付きソケットを利用します。また"127.0.0.1"
、フォールバックとして試すこともできます。MySQL / MariaDBサーバーが別のポートでリッスンする場合は、を使用します
"servername:3306"
。それが失敗した場合は、おそらくファイアウォールの問題があります。(プログラミングの質問ではなく、トピックから外れています。リモートで推測することはできません。)
egや、などの定数を使用する場合は、それらが実際に定義されていることを確認してください。
DB_USER
DB_PASSWORD
あなたが取得する場合
"Warning: Access defined for 'DB_USER'@'host'"
と"Notice: use of undefined constant 'DB_PASS'"
、それがあなたの問題です。あなたのeg
xy/db-config.php
が実際に含まれていることを確認してください。
正しく設定された
GRANT
権限を確認してください。username
+password
ペアを持つだけでは十分ではありません。各MySQL / MariaDBアカウントには、添付された一連の権限を設定できます。
これらは、接続を許可するデータベース、接続の発信元となるクライアント/サーバー、および許可するクエリを制限できます。
したがって、「アクセスが拒否されました」という警告は、特定のテーブル、または/ 、およびより一般的には何かからの
mysql_query
アクセス許可がない場合に、呼び出しに対しても表示される可能性があります。SELECT
INSERT
UPDATE
DELETE
次のようなクエリで管理者アカウントを使用して、コマンドラインクライアントごとに接続するときにアカウントのアクセス許可を調整できます。
GRANT ALL ON yourdb.* TO 'username'@'localhost';
警告が最初に表示される
Warning: mysql_query(): Access denied for user ''@'localhost'
場合は、php.iniで事前構成されたアカウント/パスワードのペアがある可能性があります。それを確認し
mysql.default_user=
、mysql.default_password=
意味のある値を持ってください。多くの場合、これはプロバイダー構成です。したがって、不一致についてはサポートに連絡してください。
共有ホスティングプロバイダーのドキュメントを見つけます。
例:HostGator、GoDaddy、1and1、DigitalOcean、BlueHost、DreamHost、MediaTemple、ixWebhosting、lunarhosting、または単にgoogle yours´。
それ以外の場合は、サポートチャネルを通じてウェブホスティングプロバイダーに相談してください。
使用可能な接続プールも使い果たしている可能性があることに注意してください。同時接続が多すぎると、アクセス拒否の警告が表示されます。(セットアップを調査する必要があります。これは、プログラミングの問題ではなく、トピック外のサーバー構成の問題です。)
libmysqlクライアントのバージョンがデータベースサーバーと互換性がない可能性があります。通常、MySQLおよびMariaDBサーバーには、ドライバーでコンパイルされたPHPを使用してアクセスできます。カスタムセットアップ、古いPHPバージョン、およびはるかに新しいデータベースサーバー、または大幅に古いデータベースサーバーがある場合は、バージョンの不一致により接続が妨げられる可能性があります。(いいえ、自分で調査する必要があります。誰もあなたの設定を推測することはできません)。
その他の参考資料:
- Serverfault:「root」@「コンピュータの名前」のmysqlアクセスが拒否されました
- 警告:mysql_connect():アクセスが拒否されました
- 警告:mysql_select_db()ユーザー '' @ 'localhost'のアクセスが拒否されました(パスワードを使用:NO)
- PHPMyAdminを使用してユーザー 'root' @ 'localhost'のアクセスが拒否されました
ところで、あなたはおそらく
mysql_*
もう関数を使いたくないでしょう。新規参入者はmysqliに移行することがよくありますが、これも同様に面倒です。代わりに、PDOとプリペアドステートメントを読んでください。
$db = new PDO("mysql:host=localhost;dbname=testdb", "username", "password");
警告:ゼロ除算
警告メッセージ「ゼロ除算」は、新しいPHP開発者の間で最もよく聞かれる質問の1つです。このエラーは例外を引き起こさないため、一部の開発者は、式の前にエラー抑制演算子@を追加することにより、警告を抑制することがあります。例えば:
$value = @(2 / 0);
ただし、他の警告と同様に、最善のアプローチは、警告の原因を突き止めて解決することです。警告の原因は、0で除算しようとした場合、0に等しい変数、または結果が「未定義」になるために割り当てられていない変数(NULL == 0のため)から発生します。
この警告を修正するには、式を書き直して、値が0でないことを確認する必要があります。そうである場合は、別のことを行います。値がゼロの場合は、除算しないか、値を1に変更してから除算する必要があります。これにより、除算は、追加の変数のみで除算したのと同じになります。
if ( $var1 == 0 ) { // check if var1 equals zero
$var1 = 1; // var1 equaled zero so change var1 to equal one instead
$var3 = ($var2 / $var1); // divide var1/var2 ie. 1/1
} else {
$var3 = ($var2 / $var1); // if var1 does not equal zero, divide
}
関連する質問:
致命的なエラー:クラスClosureのオブジェクトを文字列に変換できませんでした
これは、無名関数(またはクロージャ)を実行していないことを意味します。
この例では、矢印関数を使用してエラーがスローされます。
echo $fn = fn($x = 42) => $x;
または任意の匿名関数の場合
echo function($x = 42) { return $x; };
このエラーを解決するには、クロージャーを実行する必要があります。
echo $fn = (fn($x = 42) => $x)(30); // take notice of the 2 sets of brackets
echo (function($x = 42) { return $x; })(30);
非推奨:中括弧を使用した配列および文字列オフセットアクセス構文は非推奨になりました
{}
PHP 7.4.0より前のバージョンでは、文字列オフセットと配列要素に中括弧でアクセスできました。
$string = 'abc';
echo $string{0}; // a
$array = [1, 2, 3];
echo $array{0}; // 1
これはPHP7.4.0以降非推奨になり、警告が生成されます。
非推奨:中括弧を使用した配列および文字列オフセットアクセス構文は非推奨になりました
[]
文字列オフセットと配列要素にアクセスするには、角括弧を使用する必要があります。
$string = 'abc';
echo $string[0]; // a
$array = [1, 2, 3];
echo $array[0]; // 1