変数のみを参照渡しする必要があります


246
// Other variables
$MAX_FILENAME_LENGTH = 260;
$file_name = $_FILES[$upload_name]['name'];
//echo "testing-".$file_name."<br>";
//$file_name = strtolower($file_name);
$file_extension = end(explode('.', $file_name)); //ERROR ON THIS LINE
$uploadErrors = array(
    0=>'There is no error, the file uploaded with success',
    1=>'The uploaded file exceeds the upload max filesize allowed.',
    2=>'The uploaded file exceeds the MAX_FILE_SIZE directive that was specified in the HTML form',
    3=>'The uploaded file was only partially uploaded',
    4=>'No file was uploaded',
    6=>'Missing a temporary folder'
);

何か案は?2日後も立ち往生しています。


回答:


515

の結果をexplode変数に割り当て、その変数をに渡しますend

$tmp = explode('.', $file_name);
$file_extension = end($tmp);

問題は、end配列の内部表現を変更するため(つまり、現在の要素のポインターが最後の要素を指すようにするため)、参照が必要になることです。

の結果はexplode('.', $file_name)参照にできません。これはPHP言語の制限であり、おそらく単純化のために存在します。


12
どうもありがとうございました。私の問題を解決しました。
Frank Nwoko、2011年

1
@Oswald、を使用して警告をオフにできますerror_reporting。そうしても安全ですか?
Pacerier 2014

9
オフにしても安全error_reportingです。エラーを盲目的に無視することは安全ではありません。オフにすることerror_reportingは、盲目的にエラーを無視するための主要なステップです。運用環境では、display_errors代わりにオフにして、エラーをログファイルに書き込みます。
Oswald 2014

機能していません。以下の答え-二重括弧-が機能します。
bbe

ありがとう、たくさんの時間を節約してください!
サイモン2017

52

PHP 7互換の適切な使用法:

$fileName      = 'long.file.name.jpg';
$tmp           = explode('.', $fileName);
$fileExtension = end($tmp);

echo $fileExtension;
// jpg

3
変だ。それは機能しますが、どうですか?@プレフィックスと同様に、警告を抑制しますか?
Nigel Alderton、2014

6
では、なぜかっこを追加するとエラーが削除されるのですか?
Nigel Alderton 2014年

8
私はこの癖を調査しましたが、それはバグのようです?PHPパーサ二重カッコ「(())」基準が普通値に変換させます。このリンクの詳細。
Callistino 2014

26
私はこれが好きですが、同時に好きではありません。私の日を台無しにしてくれてありがとう:-)
Billynoah

4
php7では警告が引き続き発行されます。php.net/manual/en/...
コスタ

49

エラーが発生する理由は他の誰もがすでにあなたに教えてくれましたが、ここにあなたがやりたいことをするための最良の方法があります: $file_extension = pathinfo($file_name, PATHINFO_EXTENSION);


1
同意する。適切なAPIがある場合は、文字列操作を使用してファイルパスを解析しても意味がありません。
gd1 2014年

18

explode()から配列を変数に保存してから、この変数でend()を呼び出します。

$tmp = explode('.', $file_name);
$file_extension = end($tmp);

ところで、私はこのコードを使用してファイル拡張子を取得します。

$ext = substr( strrchr($file_name, '.'), 1);

どこのstrrchr最後の後の文字列を抽出.し、substr遮断.


9

これを試して:

$parts = explode('.', $file_name);
$file_extension = end($parts);

その理由は、の引数endが参照によって渡されるためです。これendは、内部ポインターを最終要素に進めることによって配列を変更するためです。変数を渡さない場合、参照が指すものはありません。

詳細についてendは、PHPのマニュアルを参照してください。


8

PHP end()は、変更したいものへの参照を期待しているため、文句を言います(変数のみにすることができます)。ただし、最初に変数に保存せずにexplode()直接の結果を渡しend()ます。explode()があなたの値を返す瞬間、それはメモリにのみ存在し、変数はそれを指し示しません。存在しない何か(またはメモリ内で不明なもの)への参照を作成することはできません。

または言い換えれば、PHPは知らない、あなたが彼に与える値が直接の値であるか、または値への単なるポインタであるか(ポインタも変数(整数)であり、実際の値であるメモリのオフセットを格納する)常駐)。したがって、PHPは常にポインター(参照)を期待します。

ただし、これはPHP 7での通知(非推奨ではない)にすぎないため、通知のエラーレポートを完全に非アクティブ化する代わりに、通知を無視して無視演算子を使用できます。

$file_extension = @end(explode('.', $file_name));

3
@OskarCalvoそれも私の哲学です。しかし、これはエラーではありません-PHPはこれを「通知」として扱います。そして、それはここで他の答えに対する代替の「解決策」であり、誰もそれを直接言及しませんでした。explode他の人がここに書いたように、より良い方法は一時変数に値を保存することです。ただし、これもエラーではないため、この演算子を使用しても問題ありません。PHPは一般にエラー処理に長けています。したがって、私は使用することをお勧めset_error_handlerし、set_exception_handlerエラー処理のためとクリーンなソリューションとして。
ウィザード

4

配列にすぐにインデックスを付けることができないのと同じように、配列に対してendを呼び出すこともできません。最初に変数に割り当ててから、endを呼び出します。

$basenameAndExtension = explode('.', $file_name);
$ext = end($basenameAndExtension);

4

end(...[explode('.', $file_name)])PHP 5.6以降で機能しています。これは、PHPドキュメント自体ではなく、RFCで文書化されています


2

10年以上フラグを立てますが、正常に動作して期待値を返すため、小さなstfu演算子は、あなたが探している最も良い悪い習慣です。

$file_extension = @end(explode('.', $file_name));

0

PHP公式マニュアル:end()

パラメーター

array

配列。この配列は関数によって変更されるため、参照によって渡されます。つまり、参照によって渡されるのは実際の変数だけなので、配列を返す関数ではなく、実際の変数を渡す必要があります。


3
公式マニュアルから引用して、自分の手で書き直さないでください。また、既存のものよりもあなたの答えをよくすることを検討してください。
Victor Polevoy、

-1

まず、このような変数に値を格納する必要があります

$value = explode("/", $string);

次に、end関数を使用して、このような配列から最後のインデックスを取得できます

echo end($value);

うまくいくと思います。


-3

$ file_extension = end(explode( '。'、$ file_name)); //この行のエラー

この行を次のように変更します。

$ file_extension = end( explode ( '。'、$ file_name))); //エラーなし

テクニックは簡単です。爆発用のブラケットをもう1つ入れてください。

(explode())の場合、それだけが独立して実行できます。

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