リファレンス-このエラーはPHPで何を意味しますか?


1137

これは何ですか?

これは、PHPのプログラミング中に発生する可能性のある警告、エラー、通知に関する多数の回答であり、それらを修正する方法がありません。これはコミュニティWikiでもあるため、このリストへの追加と維持に参加するよう、どなたでもご参加いただけます。

どうしてこれなの?

「ヘッダーは既に送信されました」「非オブジェクトのメンバーを呼び出すなどの質問がスタックオーバーフローで頻繁にポップアップします。これらの質問の根本的な原因は常に同じです。したがって、これらの質問に対する回答は通常、それらを繰り返し、特定のケースで変更する行をOPに示します。これらの回答はOPの特定のコードにのみ適用されるため、サイトに価値を追加しません。同じエラーを持つ他のユーザーは、ローカライズされているため、ソリューションを簡単に読み取ることができません。根本的な原因を理解したら、エラーを修正するのは簡単です。したがって、このリストは、適用する一般的な方法でソリューションを説明しようとしています。

ここで何をすればいいですか?

質問がこの質問の重複としてマークされている場合は、以下のエラーメッセージを見つけて、修正をコードに適用してください。通常、回答には、一般的な回答だけでは明確にできない場合に備えて調査するためのリンクがさらに含まれています。

貢献したい場合は、「お気に入り」のエラーメッセージ、警告または通知、回答ごとに1つ、それが何を意味するのかについての簡単な説明(マニュアルページで用語を強調しているだけの場合でも)、可能な解決策またはデバッグアプローチ、価値のある既存のQ&Aのリスト。また、既存の回答を改善してください。

リスト

また、次を参照してください。


7
また、コメントからディスカッションを移動するには、このメタ質問に移動しください
Earlz



回答:


275

警告:ヘッダー情報を変更できません-ヘッダーはすでに送信されています

スクリプトがHTTPヘッダーをクライアントに送信しようとしたが、以前にすでに出力があったため、ヘッダーがすでにクライアントに送信された場合に発生します。

これはでE_WARNINGあり、スクリプトを停止しません。

典型的な例は、次のようなテンプレートファイルです。

<html>
    <?php session_start(); ?>
    <head><title>My Page</title>
</html>
...

session_start()この関数は、クライアントにセッションクッキーでヘッダーを送信しようとします。しかし、PHPは<html>要素を出力ストリームに書き込んだときにすでにヘッダーを送信していました。session_start()上に移動する必要があります。

これを解決するは、コードが警告をトリガーするの行を確認して、出力先を確認します。ヘッダー送信コードをそのコードの前に移動します。

見落とされがちな出力は、PHPの終了後の新しい行?>です。それが?>ファイルの最後のものであるとき、それを省略することは標準的な習慣と考えられています。同様に、この警告のもう1つの一般的な原因は、開口部の<?php前に空のスペース、行、または非表示の文字があり、Webサーバーがヘッダーと空白/改行を送信することです。これにより、PHPが解析を開始すると、送信できなくなります。任意のヘッダー。

ファイル内に複数の<?php ... ?>コードブロックがある場合は、それらの間にスペースを入れないでください。(注:自動的に作成されたコードがある場合、複数のブロックが存在する可能性があります)

また、たとえばスクリプトのエンコーディングがBOMを使用したUTF-8である場合など、コードにバイトオーダーマークがないことを確認してください。

関連する質問:


2
WordPressを使用している場合は、テーマファイルを確認してください。サイトを新しいバージョンのWordPressにアップグレードしたときに、テーマが数年更新されていないため、テーマを更新できませんでした。この問題は発生しました。functions.phpファイルには複数の<??>間にスペースがあるブロック。
ロイレバン2013年

2
@RoyLeban「ファイルに複数のブロックが含まれている場合...」これがどういう意味かわかりません。「ブロック」とは何ですか?1つのブロックで構成され、<?php ?>「複数のブロック」は構成されます<?php ?> <?php ?>か?
Andrew Fox 14年

2
可能であれば、PHP.ini構成ファイルの「出力バッファリング」機能をオンにしてください。これは、この問題を解決するために使用されます。HTMLファイルが出力バッファーに保存され、スクリプトが停止した後にのみクライアントに送信されます。ヘッダーは別の場所で発行され、古いヘッダーは新しいヘッダーに置き換えられます。
Nidhin David 2014

191

致命的なエラー:非オブジェクトでのメンバー関数の呼び出し...

xyz->method()where 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();

条件付きブロックの外でメソッドを実行しようとすると、オブジェクトが定義されない場合があります。

関連する質問:


115

何も見られません。ページは空で白です。

ホワイトページオブデスまたはホワイトスクリーンオブデスとしても知られています。これは、エラーレポートがオフになっていて、致命的なエラー(多くの場合、構文エラー)が発生した場合に発生します。

エラーログを有効にしている場合は、エラーログに具体的なエラーメッセージが表示されます。これは通常、中央の場所(たとえば/var/log/apache2、多くのLinux環境)またはスクリプト自体のディレクトリ(共有ホスティング環境で使用されることもあります)の「php_errors.log」というファイルにあります。

エラーの表示を一時的に有効にする方が簡単な場合もあります。次に、白いページにエラーメッセージが表示されます。これらのエラーはWebサイトにアクセスするすべての人に表示されるため、注意してください。

これは、スクリプトの先頭に次のPHPコードを追加することで簡単に実行できます。

ini_set('display_errors', 1); error_reporting(~0);

コードはエラーの表示をオンにし、レポートを最高レベルに設定します。

ini_set()は実行時に実行されるため、解析/構文エラーには影響しません。これらのエラーはログに表示されます。それらを出力(ブラウザなど)にも表示する場合は、display_startup_errorsディレクティブをに設定する必要がありますtrue。いずれかでこれを行うphp.iniかに.htaccessまたはで設定に影響を与える他の方法の前に、実行時

同じメソッドを使用して、log_errorsおよびerror_logディレクティブを設定し、独自のログファイルの場所を選択できます。

ログを確認するか、ディスプレイを使用すると、はるかに優れたエラーメッセージと、スクリプトが停止するコード行が表示されます。

関連する質問:

関連するエラー:


3
error_reporting(~0);なんで-1?これが~0評価結果であり、非常にわかりにくいです。
FABRICIOマット

3
どちらも同様に不可解だと思います。~0より明示的なIMOです。空のビットセットを無効にします。つまり、すべてのフラグを有効にします。-1はCのstrpos()のように「見つかりません」を表すものではありませんが、-1はバイナリ1111'1111'1111'1111(32ビット)であるため、すべてのフラグが設定されたビットセットとして表します。
nalply 2013年

2
おっと、1111'1111'1111'1111実際には16ビットですが、私が何を言っているのか理解していただければ幸いです。
nalply 2013年

3
@IvanSolntsev、申し訳ありませんが、5.4より前のバージョンの場合、にE_STRICTは含まれていませんE_ALLphp.net/manual/en/errorfunc.constants.phpまでスクロールし、までスクロールしE_STRICTます。
nalply 2014年

102

注意:未定義のインデックス

配列に存在しないキーで配列にアクセスしようとすると発生します。

Undefined Index通知の典型的な例は(デモ)です

$data = array('foo' => '42', 'bar');
echo $data['spinach'];
echo $data[1];

両方spinach1引き起こし、アレイ内に存在しないE_NOTICEトリガーします。

解決策は、そのインデックスにアクセスする前に、インデックスまたはオフセットが存在することを確認することです。これは、プログラムのバグを修正して、予想どおりにこれらのインデックスが存在することを確認する必要があることを意味します。それとも、インデックスが使用して存在するかどうかをテストする必要があることを意味しますarray_key_existsisset

$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

関連する質問:


私が使用する傾向があるif(!empty($_POST['message'])){ //do stuff }
kurdtpage '28

85

警告: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*MySQL結果リソースもパラメーターとして期待する他の関数は、同じ理由で同じエラーを生成します。


5
ただのメモ。それmysql_queryが十分に悪いわけではない場合or die、その上に追加することは傷害に侮辱を追加することです。
マダラのゴースト

私が遭遇する問題は$res = mysql_query($query)、クエリが成功した場合に1を返すため、真と見なされます。従って結果通過するとき mysql_query mysql_fetch_array() 通知を示します。
mboy 2016年

@mboy SELECT、SHOW、DESCRIBE、EXPLAIN、および結果セットを返すその他のステートメントの場合、mysql_query()は成功した場合にリソースを返し、エラーの場合にFALSEを返します。他のタイプのSQLステートメント、INSERT、UPDATE、DELETE、DROPなどの場合、mysql_query()は成功した場合にTRUEを、エラーの場合にFALSEを返します。
xdazz 2016年

私はこのエラーを取り除くことはできませんので、私はTRUE、挿入、更新リターンを直面しています問題である@xdazzはmysql_fetch_array() expects parameter 1 to be resource, boolean given in select -を参照してくださいgist.github.com/romelemperado/93af4cdbd44ebf3a07cbfa0e3fc539d7 このエラーを取り除くのgitへの任意の提案を?
mboy 2016年

2
@mboy mysql_fetch_array()は選択クエリ用、挿入と更新用で、結果セットをフェッチする必要はありません(フェッチできる結果セットはありません)。
xdazz 2016年

79

致命的なエラー:オブジェクトコンテキストにないときに$ thisを使用する

$this割り当てられないPHPの特殊変数です。存在しないコンテキストでアクセスされた場合、この致命的なエラーが発生します。

このエラーは発生する可能性があります:

  1. 非静的メソッドが静的に呼び出された場合。例:

    class Foo {
       protected $var;
       public function __construct($var) {
           $this->var = $var;
       }
    
       public static function bar () {
           // ^^^^^^
           echo $this->var;
           //   ^^^^^
       }
    }
    
    Foo::bar();

    修正方法:コードをもう一度確認してください。$thisオブジェクトコンテキストでのみ使用でき、静的メソッドでは使用しないでください。また、静的メソッドは非静的プロパティにアクセスしないでください。self::$static_property静的プロパティにアクセスするために使用します。

  2. クラスメソッドのコードは、正常な機能または単にグローバルスコープにコピーされている場合維持$this特別な変数。
    修正方法:コードを確認$thisし、別の置換変数に置き換えます。

関連する質問:

  1. 非静的メソッドを静的として呼び出す:PHP致命的エラー:オブジェクトコンテキストにないときに$ thisを使用する
  2. コードのコピー:致命的なエラー:オブジェクトコンテキストにないときに$ thisを使用する
  3. Stackoverflowに関するすべての「オブジェクトコンテキストにないときの$ thisの使用」に関する質問

2
また、これがクロージャーでどのように機能するか(非静的メソッドでも)、5.4でどのように「修正」されるかについても言及する必要があります。
ケンダルホプキンス

2
@hakreクロージャー内の静的呼び出しについて話していました。のように$closure = function() { self::method(); }
ケンドールホプキンス

2
@KendallHopkins:それは別のエラーです:「致命的エラー:自分にアクセスできません::アクティブなクラススコープがない場合」ただし$this、特注の「致命的エラー:オブジェクトコンテキストにないときに$ thisを使用する」をトリガーできます$closure = function() { $this->method(); };
hakre

75

致命的なエラー:未定義の関数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れるのは1回だけcreateFn()です。への後続の呼び出しcreateFn()は、既存の関数の再宣言に関するエラーをトリガーすることに注意してください。

これは、PHP組み込み関数でも確認できます。公式マニュアルで関数を検索してみて、それがどの「拡張機能」(PHPモジュール)に属しているか、およびPHPのどのバージョンがそれをサポートしているかを確認してください。

拡張機能が欠落している場合は、その拡張機能をインストールして、php.iniで有効にします。関数が表示される拡張機能については、PHPマニュアルのインストール手順を参照してください。パッケージマネージャー(aptDebianまたはUbuntu、yumRed HatまたはCentOS)、またはコントロールパネルを使用して、拡張機能を有効化またはインストールすることもできます。共有ホスティング環境。

使用しているものより新しいバージョンのPHPで関数が導入された場合は、マニュアルまたはそのコメントセクションで代替実装へのリンクを見つけることができます。PHPから削除されている場合は、不要になった可能性があるため、その理由に関する情報を探してください。

インクルードが欠落している場合は、関数を呼び出す前に、関数を宣言しているファイルをインクルードしてください。

タイプミスの場合は、タイプミスを修正します。

関連する質問:


73

解析エラー:構文エラー、予期しないT_XXX

予期しない場所にT_XXXトークンがある場合、不均衡な(余分な)括弧がある場合、php.iniでそれをアクティブ化せずに短いタグを使用した場合などに発生します。

関連する質問:

詳細については、以下を参照してください。


70

致命的なエラー:関数の戻り値を書き込みコンテキストで使用できません

これは通常、関数をで直接使用するときに発生しemptyます。

例:

if (empty(is_null(null))) {
  echo 'empty';
}

これはemptyが言語構造であり関数ではないためです。5.5より前のPHPバージョンでは、式を引数として呼び出すことはできません。PHP 5.5より前では、引数to empty()変数でなければなりませんが、PHP 5.5以降では任意の式(関数の戻り値など)を使用できます。

emptyは、その名前にもかかわらず、変数が「空」であるかどうかを実際にチェックしません。代わりに、変数が存在しないかどうかを確認します== false。式(is_null(null)例のように)は常に存在すると見なされるため、ここでemptyはfalseに等しいかどうかのみをチェックしています。たとえば、empty()ここでを置き換えるか、明示的にfalseと比較することができます。!if (!is_null(null))if (is_null(null) == false)

関連する質問:


64

MySQL:SQL構文にエラーがあります。MySQLサーバーのバージョンに対応するマニュアルで、near ... at line ...を使用するための正しい構文を確認してください。

このエラーは、MySQLクエリに渡されたデータを適切にエスケープするのを忘れたことが原因で発生することがよくあります。

してはいけないことの例(「悪い考え」):

$query = "UPDATE `posts` SET my_text='{$_POST['text']}' WHERE id={$_GET['id']}";
mysqli_query($db, $query);

このコードは、http://example.com/edit.php?id = 10(投稿n°10を編集する)などのURLを使用して、送信するフォームを含むページに含めることができます。

送信されたテキストに単一引用符が含まれている場合はどうなりますか?$query最終的に:

$query = "UPDATE `posts` SET my_text='I'm a PHP newbie' WHERE id=10';

また、このクエリがMySQLに送信されると、途中に余分な一重引用符が含まれているため、構文が間違っているというメッセージが表示されます。

このようなエラーを回避するには、しなければならない、常にクエリで使用する前にデータをエスケープ。

SQLクエリで使用する前にデータをエスケープすることも非常に重要です。そうしないと、スクリプトがSQLインジェクションに対して開かれるためです。SQLインジェクションは、レコード、テーブル、またはデータベース全体の変更、損失、または変更を引き起こす可能性があります。これは非常に深刻なセキュリティ問題です!

ドキュメンテーション:


3
さらに、そうしないと、サイトはボットによって自動的にハッキングされます
apscience

2
@gladoscc [編集]をクリックして、回答を変更します。改善できることは承知しています。
Jocelyn、2012年

2
または、準備されたSQLクエリを使用します。
Matej 2013

53

致命的なエラー:XXXバイトの許容メモリサイズを使い果たしました(XXXバイトを割り当てようとしました)

スクリプトを実行するのに十分なメモリがありません。PHPはメモリ制限に達し、実行を停止します。このエラーは致命的であり、スクリプトは停止します。メモリ制限の値は、php.iniファイルで、またはini_set('memory_limit', '128 M');スクリプトで使用して構成できます(これにより、で定義された値が上書きされますphp.ini)。メモリ制限の目的は、1つのPHPスクリプトが使用可能なメモリをすべて消費してWebサーバー全体を停止させないようにすることです。

最初に行うことは、スクリプトに必要なメモリの量を最小限に抑えることです。たとえば、大きなファイルを変数に読み込んでいる場合や、データベースから多くのレコードをフェッチしてそれらをすべて配列に格納している場合、大量のメモリを使用する可能性があります。代わりにコードを変更して、ファイルを1行ずつ読み取るか、データベースレコードを1つずつフェッチして、それらをすべてメモリに保存しないようにします。これには、舞台裏で何が行われているのか、いつデータがメモリに格納されているのか、他の場所に格納されているのかを少し概念的に認識する必要があります。

スクリプトがメモリを集中的に使用していないときにこのエラーが発生した場合は、コードをチェックしてメモリリークがないかどうかを確認する必要があります。memory_get_usage機能はあなたの友達です。

関連する質問:


53

解析エラー:構文エラー、予期しない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文字列のマニュアルページの変数の解析に関するセクションをご覧ください。


45

警告:[関数]:ストリームを開くことができませんでした:[理由]

あなたが通常でファイルを呼び出すときに起こるincluderequireまたはfopenとPHPはファイルを見つけるか、ファイルをロードするために十分ではない権限を持っていませんでした。

これにはさまざまな理由が考えられます。

  • ファイルパスが間違っています
  • ファイルパスは相対パスです
  • インクルードパスが間違っています
  • 権限が厳しすぎる
  • SELinuxが有効です
  • などなど ...

よくある間違いの1つは、絶対パスを使用しないことです。これは、簡単に完全なパスまたは使用することによって解決することができる魔法の定数のように__DIR__dirname(__FILE__)

include __DIR__ . '/inc/globals.inc.php';

または:

require dirname(__FILE__) . '/inc/globals.inc.php';

正しいパスが使用されていることを確認することは、これらの問題のトラブルシューティングの1つのステップです。これは、存在しないファイル、ファイルシステムのアクセス権、またはPHP自体によるアクセスベースの制限に関連している可能性もあります。

この問題をすばやく解決する最善の方法は、以下のトラブルシューティングチェックリストに従うことです。

関連する質問:

関連するエラー:


44

解析エラー:構文エラー、予期しないT_PAAMAYIM_NEKUDOTAYIM

スコープ解決演算子は、ヘブライ語פעמייםから「Paamayim Nekudotayim」とも呼ばれます。「ダブルコロン」を意味します。

このエラーは通常、誤っ::てコードを入力した場合に発生します。

関連する質問:

ドキュメンテーション:


このエラーをトリガーする最も簡単な方法は、a()::b;またはを実行すること$a=::;です。
Ismael Miguel

43

通知:未定義の定数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拡張機能またはライブラリがないことを示している可能性もあります。

関連する質問:


2
最も一般的な原因は、配列ではなく変数の前で$を忘れることです。
2012年

42

致命的なエラー:クラス[クラス名]を再宣言できません

致命的なエラー:[関数名]を再宣言できません

この手段どちらか二度同じ機能/クラス名を使用して、そのうちの1の名前を変更する必要がある、またはあなたが使用しているので、それはしているrequireか、includeあなたが使用する必要がありますどこrequire_onceinclude_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ことで、の定義を含むファイルがMyClass1回だけロードされ、エラーが回避されることが確実になります。


3
オートローディングの使用について言及する価値はありますか?PSR-4または現在非推奨のPSR-0などの標準でも、require / includeを使用する必要をなくすことで、これをかなり取り除くことができます(いくつかの奇妙なエッジケースを除きます)。
DanielM 2015年

39

通知:未定義の変数

以前に定義されていない変数を使用しようとすると発生します。

典型的な例は

foreach ($items as $item) {
    // do something with item
    $counter++;
}

$counter以前に定義していない場合は、上記のコードが通知をトリガーします。

正しい方法は、たとえそれが空の文字列であっても、それを使用する前に変数を設定することです

$counter = 0;
foreach ($items as $item) {
    // do something with item
    $counter++;
}

通知:未定義のプロパティ

このエラーはほとんど同じことを意味しますが、オブジェクトのプロパティを参照しています。上記の例を再利用すると、counterプロパティが設定されていないため、このコードはエラーをトリガーします。

$obj = new stdclass;
$obj->property = 2342;
foreach ($items as $item) {
    // do something with item
    $obj->counter++;
}

関連する質問:


35

解析エラー:構文エラー、予期しない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);

PHPエラー報告

また、入力中に解析エラーを通知するIDEを使用することをお勧めします。以下を使用できます。

  1. NetBeans(すばらしい美しさ、フリーソフトウェア)(私の意見では最高)
  2. PhpStorm(ゴードンおじさんはこれが大好きです:P、有料プラン、独自の無料ソフトウェアが含まれています)
  3. Eclipse(美女と野獣、フリーソフトウェア)

関連する質問:


34

注意:初期化されていない文字列オフセット: *

名前が示すように、このようなタイプのエラーは、存在しないキーを持つ配列から反復したり、値を見つけたりする可能性が高いときに発生します。

あなたを考慮して、からのすべての手紙を表示しようとしています $string

$string = 'ABCD'; 
for ($i=0, $len = strlen($string); $i <= $len; $i++){
    echo "$string[$i] \n"; 
}

上記の例では(online demo)が生成されます

A
B
C
D
Notice: Uninitialized string offset: 4 in XXX on line X

そして、スクリプトがエコーDを終了するとすぐにエラーが発生します。これは、for()ループ内で、そこから最初から5番目までの文字列文字を表示するようにPHPに指示したからです'ABCD'。ただし、ループが開始して0エコーするため、Dに達するまで4に、オフセットエラーがスローされます。

同様のエラー:


32

通知:非オブジェクトエラーのプロパティを取得しようとしています

オブジェクトがないときにオブジェクトのプロパティにアクセスしようとすると発生します。

非オブジェクト通知の典型的な例は、

$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;

関連するエラー:


1
json_decodestdclassデフォルトでのインスタンスを返すようになったため、サンプルコード実際に機能します。
Hugo Zink、2016年

@HugoZink:それは実際に(と常にやった)その例えば、配列を返すん:3v4l.org/SUDe0は -また、あなたはそれをあなたの執筆のための参照を提供してくださいすることができ、「json_decode今のインスタンスを返しstdclass、デフォルトでは」?変更ログでそれを見つけることができません。
2016年

json_decodeのPHPマニュアルのページによると、デフォルトでは、assocパラメーターはfalseに設定されています。このパラメーターは、関数がstdclass連想配列の代わりにを返すかどうかを決定します。
Hugo Zink、2016年

json_decode('[{"name": "hakre"}]', true)配列、それ以外の場合はstdclassオブジェクトを返します
zanderwar '25

29

警告:open_basedirの制限が有効になっています

この警告は、ファイルおよびディレクトリへのアクセスに関連するさまざまな機能とともに表示されることがあります。構成の問題について警告します。

表示される場合は、一部のファイルへのアクセスが禁止されていることを意味します。

警告自体は何も壊しませんが、ほとんどの場合、ファイルアクセスが禁止されている場合、スクリプトは適切に機能しません。

修正は通常、PHP設定を変更することで、関連する設定が呼び出されますopen_basedirます。

間違ったファイル名やディレクトリ名が使用されている場合があるため、修正は正しいものを使用することです。

関連する質問:


1
これは、共有ホスト上で最も頻繁に発生し、人々は通常:-)ディレクトリの自分自身をロックアウトしていない
uınbɐɥs

28

解析エラー:構文エラー、予期しない '['

このエラーには2つのバリアントがあります。

バリエーション1

$arr = [1, 2, 3];

この配列初期化構文は、PHP 5.4でのみ導入されました。それ以前のバージョンではパーサーエラーが発生します。可能であれば、インストールをアップグレードするか、古い構文を使用します。

$arr = array(1, 2, 3);

マニュアルのこの例も参照してください。

バリエーション2

$suffix = explode(',', 'foo,bar')[1];

配列逆参照関数の結果もPHP 5.4で導入されました。アップグレードできない場合は、(一時的な)変数を使用する必要があります。

$parts = explode(',', 'foo,bar');
$suffix = $parts[1];

マニュアルのこの例も参照してください。


23

警告:[関数]はパラメーター1がリソースであり、ブール値が指定されていることを期待しています

警告のより一般的なバリエーション:mysql_fetch_array()はパラメーター1がリソースであることを期待し、ブール値が与えられます

リソースはPHPのタイプです(文字列、整数、オブジェクトなど)。リソースは、固有の意味のある値を持たない不透明なblobです。リソースは、特定の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);

関連するエラー:


22

警告:不正な文字列オフセット 'XXX'

これは、角括弧構文を使用して配列要素にアクセスしようとしたときに発生しますが、これは配列ではなく文字列に対して実行しているため、操作は明らかに意味がありません。

例:

$var = "test";
echo $var["a_key"];

変数が配列である必要があると思われる場合は、それがどこから来たかを確認し、そこで問題を修正してください。


20

コードが実行されない/ 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構成で短いオープンタグがオフになっているかどうかを確認することもできます。

また、PHPコードが実行されていない代わりに、ページにコードが表示されることも確認してください。


18

警告:mysql_connect():ユーザー 'name' @ 'host'のアクセスが拒否されました

この警告は、無効または欠落している資格情報(ユーザー名/パスワード)を使用してMySQL / MariaDBサーバーに接続すると表示されます。だから、これは一般的にあるではないコードの問題が、サーバー構成の問題。

  • mysql_connect("localhost", "user", "pw")例については、のマニュアルページを参照してください。

  • 実際にa $usernameとを使用したことを確認します$password

    • パスワードを使用せずにアクセスすることはめったにありません-警告:が言ったときに起こったこと(using password: NO)です。
    • 通常、ローカルテストサーバーのみが、username root、パスワードなし、testデータベース名での接続を許可します。

    • コマンドラインクライアントを使用して、それらが本当に正しいかどうかをテストできます。
      mysql --user="username" --password="password" testdb

    • ユーザー名とパスワードは大文字と小文字が区別され、空白は無視されません。パスワードにのようなメタ文字が含まれている場合は$、エスケープするか、パスワードを一重引用符で囲みます

    • ほとんどの共有ホスティングプロバイダーは、UNIXユーザーアカウントに関連してmysqlアカウントを事前宣言します(プレフィックスまたは追加の数値サフィックスのみの場合もあります)。パターンまたはドキュメントについてはドキュメントを、パスワードを設定するためのCPanelまたはその他のインターフェースを参照してください。

    • コマンドラインを使用したユーザーアカウントの追加に関するMySQLのマニュアルを参照してください。管理者ユーザーとして接続すると、次のようなクエリを発行できます。
      CREATE USER 'username'@'localhost' IDENTIFIED BY 'newpassword';

    • または、AdminerWorkBench、またはその他のグラフィカルツールを使用して、アカウントの詳細を作成、確認、または修正します。

    • 資格情報を修正できない場合、インターネットに「助けてください」と尋ねても効果はありません。あなたとあなたのホスティングプロバイダーだけが、診断と修正のための権限と十分なアクセス権を持っています。

  • プロバイダーから提供されたホスト名を使用して、データベースサーバーにアクセスできることを確認します。
    ping dbserver.hoster.example.net

    • ウェブサーバーのSSHコンソールから直接確認してください。ローカル開発クライアントから共有ホスティングサーバーへのテストはほとんど意味がありません。

    • 多くの場合、サーバー名をにしたいだけで"localhost"、通常は、使用可能なときにローカルの名前付きソケットを利用します。"127.0.0.1"フォールバックとして試すこともできます。

    • MySQL / MariaDBサーバーが別のポートでリッスンする場合は、を使用します"servername:3306"

    • それが失敗する場合、おそらくファイアウォールの問題があります。(プログラミングの質問ではなく、トピックとは関係ありません。リモートの推測支援はできません。)

  • eg やなどの定数を使用する場合は、それらが実際に定義されていることを確認してください。DB_USERDB_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アクセスする権限がない場合、「アクセスが拒否されました」という警告が呼び出しに対して表示されることもあります。SELECTINSERTUPDATEDELETE

    • 次のようなクエリで管理者アカウントを使用して、コマンドラインクライアントごとに接続するときに、アカウントの権限調整できます。
      GRANT ALL ON yourdb.* TO 'username'@'localhost';

  • 最初に警告が表示されたWarning: mysql_query(): Access denied for user ''@'localhost'場合は、php.iniで事前設定されたアカウント/パスワードのペアがある可能性があります

    • 確認してmysql.default_user=mysql.default_password=意味のある値を設定してください。

    • 多くの場合、これはプロバイダー構成です。したがって、不一致についてはサポートに連絡してください。

  • 共有ホスティングプロバイダーのドキュメントを見つけます。

  • 利用可能な接続プール使い果たした可能性もあります。同時接続が多すぎると、アクセス拒否の警告が表示されます。(セットアップを調査する必要があります。これは、プログラミングの問題ではなく、サーバー構成の問題です。)

  • libmysqlクライアントのバージョンがデータベースサーバーと互換性がない可能性があります。通常、MySQLサーバーとMariaDBサーバーには、ドライバーでコンパイルされたPHPでアクセスできます。カスタムセットアップまたは古いPHPバージョンと、はるかに新しいデータベースサーバーがある場合、または著しく古いものである場合、バージョンの不一致により接続が妨げられる可能性があります。(いいえ、あなた自身を調査する必要があります。誰もあなたの設定を推測することはできません)。

その他の参照:

ところで、おそらくmysql_*関数をもう使いたくないでしょう。新規参入者はしばしばmysqliに移行しますが、これは同じくらい退屈です。代わりにPDOと準備されたステートメントを読んでください
$db = new PDO("mysql:host=localhost;dbname=testdb", "username", "password");


2
mysqlはphp-ini設定を介して自動接続を許可します。同じエラーメッセージが、異なるコマンドの前に付けられて表示されます。 .. " -注意してください。
hakre 2015

ハ、完全に忘れちゃった!(おそらく最後PHP3とか、そうすることを使用。)
マリオ

18

注意:配列から文字列への変換

これは、配列を文字列として処理しようとした場合にのみ発生します。

$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
}

この通知が予期しない場所に表示された場合、それは、文字列が実際には配列であると考えていた変数を意味します。つまり、コードにバグがあり、この変数が期待する文字列ではなく配列になるということです。


12

警告:ゼロによる除算

警告メッセージ「ゼロによる除算」は、新しいPHP開発者の間で最もよく寄せられる質問の1つです。このエラーによって例外が発生することはないため、一部の開発者は、式の前にエラー抑制演算子@を追加することにより、警告を抑制します。例えば:

$value = @(2 / 0);

ただし、他の警告と同様に、最善の方法は警告の原因を追跡して解決することです。警告の原因は、結果が「未定義」になるため、0、0に等しい変数、または割り当てられていない変数(NULL == 0であるため)で除算しようとするインスタンスから発生します。

この警告を修正するには、式を書き直して、値が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
}

関連する質問:


0の場合に1に設定するとエラーが停止しますが、これは、使用しない方がよいと言った抑制(私は同意します)よりも優れていますか?ほとんどの場合、他のメッセージまたは値が返される可能性があることをお勧めします。
ジェームズ

場合は、この例の場合、$var1== 0を行い、その後あなただけ設定することができます$var3$var2。それを行わなくても、割り当てはどちらの場合も同じであるため、elseはまったく必要ありません。そのため、elseを割り当てず、外側に割り当てますif
James

8

厳格な規格:非静的メソッド[<class> :: <method>]は静的に呼び出すべきではありません

静的であったためにクラスで非静的メソッドを呼び出そうとしたときに発生E_STRICTし、error_reporting()設定にもフラグがあります。

例:

class HTML {
   public function br() {
      echo '<br>';
   }
}

HTML::br() または $html::br()

に追加E_STRICTしないことでerror_reporting()、このエラーを実際に回避できます。たとえば、

error_reporting(E_ALL & ~E_STRICT);

PHP 5.4.0以降E_STRICTE_ALL[ ref ]に含まれています。しかし、それは助言できません。解決策は、目的の静的関数を実際のものとして定義することstaticです。

public static function br() {
  echo '<br>';
}

または従来通りに関数を呼び出します:

$html = new HTML();
$html->br();

関連する質問:


7

非推奨:中括弧を含む配列と文字列のオフセットアクセス構文は非推奨です

文字列オフセットと配列要素は{}、PHP 7.4.0より前の中括弧でアクセスできました。

$string = 'abc';
echo $string{0};  // a

$array = [1, 2, 3];
echo $array{0};  // 1

これはPHP 7.4.0以降廃止され、警告を生成します:

非推奨:中括弧を含む配列と文字列のオフセットアクセス構文は非推奨です

[]文字列オフセットと配列要素にアクセスするには、角括弧を使用する必要があります。

$string = 'abc';
echo $string[0];  // a

$array = [1, 2, 3];
echo $array[0];  // 1

この変更に関するRFCは、これを機械的に修正しようとするPHP スクリプトにリンクしています。

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.