
自作の関数で、issetとemptyを一緒に判定する関数を作っているのですがエラーが出ます。
ある変数が「未定義」または「null」または「""(空白)」の場合はnullである、という関数を作りたいです。
------------------------------------------
function is_null_ex($value){
if (!isset($value)) {return true;} // 未定義かnullの場合、trueを返す
else if (strlen(strval($value)) === 0) {return true;} // 空白の場合はtrueを返す
else {return false;} // $valueに値が入っている場合はfalseを返す
}
is_null_ex($val);
------------------------------------------
上記の関数で$valueが未定義の場合にfuncを使うと、次のようなエラーが出ます。
Notice: Undefined variable: val
つまり、未定義の変数を引数に渡すとエラーが出ます。
「未定義なら関数に渡さなければ?」と思うかもしれませんが、そもそもこの関数は「未定義」または「null」または「""(空白)」を判定したい関数なのです。
この場合、どうすれば良いのでしょうか?
エラーは出ますが上記の関数で「if (!isset($value)) {return true;}」の部分できちんと判定はされています。
PHP5.3系で運用しています。
ぞうぞよろしくお願い致します。
No.2ベストアンサー
- 回答日時:
に
PHPでは原則的に未定義の変数の値を取得しようとしたときに Notice が発生して NULL 扱いになるが、参照渡しのデフォルト値の場合だけ例外的にNoticeを発生せずにNULLとして初期化される。
と書いてある。
上記のページに「強引な解決方法」が書いてあるけど、ページ読んで意味や方法が判らない場合は諦めるべし。
No.9
- 回答日時:
>> $stmt->bindValue(":name", null, PDO::PARAM_NULL);
>> ですが、
>> $stmt->bindValue(":name", null);
>> できちんとnullが入っているので問題ない気がしますが、どうでしょうか?
NULLだけが特別視されると考えるのが良さそうです。SELECTで抜き出してくる時もNULLだけは型を保っていますし、言われてみれば当然の挙動だったかもしれません。検証有難うございます。
No.8
- 回答日時:
>> $stmt->bindValue(":name", is_null_ex($val) ? null : $val);
なるほど、ちょっとこれはどうしようか迷うところですね。文字列の "0" も "" と同じ扱いで良ければ
$stmt->bindValue(":name", empty($val) ? null : $val);
と書きたいところですが、それでは困る感じでしょうか。でしたら冗長ですが
$stmt->bindValue(":name", !isset($val) || $val === "" ? null : $val);
ぐらいが妥当だと思います。エラー抑制して
$stmt->bindValue(":name", @$val == "" ? null : $val);
とする手もありますが、個人的にはこれはちょっと嫌ですね。エラーを発生するだけでパフォーマンスは大きく落ちるので、このようなコーディングを局所的にでもすることは避けるべきだと思います。塵も積もれば山となってしまうので、このような癖をつけるのはやめましょう。
(※ なお、この場合は === ではなく == にする必要があります)
-----------------------------------------------
さて、ちょっと見方を変えたソリューションを導きましょう。
【NULLや空文字列を代入して初期化しておく】
そもそも未定義かもしれない変数を使用する時点でコードが冗長になることは避けられません。これをあらかじめ初期値を代入しておくことでシンプルさを維持できます。今回の例の場合、NULLよりも空文字列を代入しておく方が型に一貫性が確保できるので望ましいと思います。
$val = "";
....
$stmt->bindValue(":name", $val === "" ? null : $val);
あとここまで書いていて気付いたのですが、bindValueは自分で型を指定しなければなりませんね。このままのコードだと全部デフォルトの文字列(PDO::PARAM_STR)が使われて文字列にキャストされてしまうので、NULLにすべきときは(PDO::PARAM_NULL)を使いましょう。
$val = "";
....
if ($val === "") {
$stmt->bindValue(":name", null, PDO::PARAM_NULL);
} else {
$stmt->bindValue(":name", $val);
}
再度のアドバイス、ありがとうございます。
最初にnullや空文字で初期化しておく・・・たしかにそうしておくのが一番ですね。
それで、最後に部分のbindValueですが、型指定については以前こちらで聞いたりネットで調べたりしたんです。そのときの質問がこちらです。
http://oshiete.goo.ne.jp/qa/8478452.html
bindValueは全て文字列にキャストされてしまうようで、PDO::PARAM_INTとかは意味ないみたいですね。
で、
$stmt->bindValue(":name", null, PDO::PARAM_NULL);
ですが、
$stmt->bindValue(":name", null);
できちんとnullが入っているので問題ない気がしますが、どうでしょうか?
No.7
- 回答日時:
エラーチェックの関数で、エラーが出るのでは困りものですが、
処理や変数の前に@をつけるとエラーを非表示にできます。
ちゃんとあるんですねぇ。
呼び出し時に、
@is_null_ex($value)
これは試していませんが、どうなんでしょうか。
is_null_ex(@$value)
function is_null_ex(@$value){
function @is_null_ex($value){
No.6
- 回答日時:
#3です
まあ私の方法を使うことはないとして、勘違いがあるようなので1点だけ補足。
>文字列を直接入れることは想定していないです。
変数名を文字列として渡してチェックするという意味です
ご理解いただいているとおり未定義の変数が渡せないのであれば
該当する変数名を文字列でわたせばチェックができます。
$x=1;
$y="x";
print $$y;//→出力「1」
というロジックです
No.5
- 回答日時:
issetとemptyは変数シンボルを対象にする関数ではない特別な構文なので、通常の考え方でラッパー関数を書くことは出来ません。
所々で毎回issetを記述するしかないです。参照渡しにすれば例外的にエラーを発生せずにNULLを自動代入出来ますが、個人的な考え方としては「未定義」と「NULL」は一緒くたにしてはいけないと思うので、このやり方は非推奨です。Qiita - PHPでの参照渡し
http://qiita.com/akisssa/items/342d742c6ce9cd30b …
(実はこれ大部分私の編集リクエストなんですがw)
但し、 isset($_POST['test']) のようにスーパーグローバル変数を対象にする場合はこれを効率化する関数があります。以下の記事中で紹介しているfilter_input関数です。
Qiita - $_GET, $_POSTなどを受け取る際の処理
http://qiita.com/mpyw/items/2f9955db1c02eeef43ea
ありがとうございます!
issetとか、普通の関数じゃない気はしていました…。
>個人的な考え方としては「未定義」と「NULL」は一緒くたにしてはいけないと思うので、このやり方は非推奨です
はい、そこはわかっています。
で、なぜnullとしたいかというと、引数の変数が「未定義」「null」「""(空白)」の場合に、データベースの値をnullにしたかったからです。
$stmt->bindValue(":name", is_null_ex($val) ? null : $val);
みたいな感じです。
filter_inputですが、スーパーグローバル変数を対象にすることはないので使用しませんでした。
No.4
- 回答日時:
変数そのものを判定するのに、変数の内容を渡すからそういうことになるんですよ。
認識の誤りです。
参照形で変数そのものを渡すべきです。
参照形では、関数内で未定義の変数に直接値を代入することができません。
PHPでの参照渡し:
関数定義で引数に & をつけると、関数内で扱う変数名が呼び出し元のスコープに存在する変数名の エイリアス のようになる。
ありがとうございます。
たしかにおっしゃる通りでした…。
実はこの参照渡し、いろんな言語で使ったりCのポインタとか、
もうごちゃごちゃしていてよくわからないんですよね。
もっと勉強しないとダメですね…。
No.3
- 回答日時:
まぁあまり頭のいい方法ではないですが
is_null_ex("val");
のように文字列で渡す手もあるかと、
その場合
function is_null_ex($value){
global $$value;
うんたらかんたら
}
と、関数外の変数を参照するためglobalで参照しないといけないかも。
クラスを使っていればそれにあわせてください
ありがとうございます。
文字列を直接入れることは想定していないです。
そもそも未定義の変数が引数の場合にnullと判定したかったので・・・。
No.1
- 回答日時:
set_error_handler — ユーザー定義のエラーハンドラ関数を設定する
この辺を工夫してなんとか実装するしか方法はないでしょうね。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- C言語・C++・C# c言語の問題です 3 2023/01/10 16:15
- JavaScript javascript作成してます。ラジオボタンで判定するコードを書いてます。 1 2023/07/18 11:03
- 大学・短大 C言語線形リストの問題です 3 2022/12/22 00:45
- Visual Basic(VBA) [Excel VBA] このコードでは行の挿入や行の消去をすると13のエラーが出てしまう。 3 2022/12/09 00:29
- C言語・C++・C# C# DatagridviewにExcelシートを反映するとエラーが出る 2 2023/05/06 17:12
- Visual Basic(VBA) VBAのユーザーフォームのテキストボックスに入力制限をしたい 6 2022/11/15 08:28
- Excel(エクセル) Excelでnullになるような式のセルをマクロで空白行と認識させるにはどうすればいいですか? 3 2023/03/13 13:42
- JavaScript HTMLでJavaScriptを使ってパスワードの強化判定のプログラムを作成しています。 一通り作っ 2 2022/10/19 01:41
- Visual Basic(VBA) VBA 改行コードの取り方 1 2022/03/22 14:14
- Excel(エクセル) VBAで “:” を含むセルの特定 2 2023/05/11 16:30
関連するカテゴリからQ&Aを探す
おすすめ情報
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
PHP.iniの設定に関して
-
デバックって何ですか?
-
ロリポップでincludeできない。
-
ajaxからのPHP呼び出し時にエラ...
-
日本語をGETで渡す場合UR...
-
awsにApacheとPHPを入れて、何...
-
フォントの色を変えるには?
-
パースエラーとは?
-
PHPでFetalなエラーが発生した場合
-
502 Bad Gatewayの解決方法
-
phpにてファイルをアップロード。
-
phpファイルを開けない(ブラウ...
-
PHPとPostgreSQL接続 (スキーマ)
-
あらゆる例外に対応できるエラ...
-
PHPでの投稿フォームで、ファイ...
-
laravelでDBの参照ができない
-
最小公倍数をPHPで求めるには
-
phpのfopenで行単位のfseekは出...
-
header("Location: ")でページ...
-
クラスの中でincludeするとき、...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
フォントの色を変えるには?
-
トランザクションが原因?DBに...
-
PHPでfatal errorが出ても無視...
-
iframeからのアクセスか、ブラ...
-
PHP8を使うと、大量のWarningが...
-
パースエラーとは?
-
PHPで、エラーがない場合のみ画...
-
error_reporting(0);にも関わら...
-
PHPにて外部サイト内容が取得不...
-
「@$変数」の「@の意味は?」
-
PHPでネットワークドライブのop...
-
PHPで特定のURLにジャンプす...
-
phpのrenameでエラーが出ます
-
ある条件に当てはまったときに...
-
「file_get_contents」で「HTTP...
-
PostgreSQLへのinsert処理
-
正規表現での最後尾のバックス...
-
require_once で読み込まれたか?
-
awsにApacheとPHPを入れて、何...
-
IIS/PHPのサイトでたまにCGIエ...
おすすめ情報