カテゴリー
SugiBlog Webデザイナー・プログラマーのためのお役立ちTips

PDOで取得したデータが、数値型なのに文字列型になってしまう

PHPのバージョンを7.4系から8.x系にバージョンアップする事案があり、変更点やシステムの動作に問題がないか等の調査をしていました。
その中で公式ページにも見当たらないことがあったので、実際にバージョンを切り替えながら検証して分かったことを共有させていただければと思います。

今回発見した問題点はPDOのプリペアドステートメントです。
セキュリティ上、脆弱性のないように開発する中で必ず使われているかと思います。

ただ、このプリペアドステートメント、数値型のデータを文字列型で返してきます。
困りますね。
しかしながらそういう仕様なので、それに合わせてコーディングするしかないわけなんですが、
これがなんと、8.1以降だと数値型で返ってるのです。

なんということでしょう・・・。

厳密な比較を行っている箇所はすべて修正しないといけません。
例えば以下のような場合です。

if($col["COLUMN_NAME_INDEX"] === "1") { ... }

このCOLUMN_NAME_INDEXのデータ型は数値型(Integer)ですが、PDOのプリペアドステートメントで返ってくるのは文字列型のため、このような比較をしています。
これが8.1以降だとCOLUMN_NAME_INDEXのデータが数値型のため、(1 === "1")という式となり判定はfalseとなります。

この問題については、コーディング自体に間違いがあるわけではありませんので、コード解析ツール等にかけても出てこないと思います。
原因の究明に時間がかかったので、ここに記しておきます。

更に調査したところ、PDOの設定でエミュレート・モードというものがあり、有効/無効(true/false)で設定します。
実際には今回の件に関する具体的な設定ではないのですが、この設定を無効(false)に設定してみると8.0でも数値型で返ってきました。

PDO::setAttribute(PDO::ATTR_EMULATE_PREPARES, false)

検証したバージョンは次の通りです。
7.4.29
8.0.28
8.1.17
8.2.4

公式:PHP 8.0.x から PHP 8.1.x への移行

437 views

PHPで10進数を2・8・16進数に変換

PHPで10進数から2・8・16進数へと、基数変換を行う方法をご紹介します。

まずは10進数で変換する値を宣言しておきます。

$dec = 500;

2進数に変換

書式:decbin(int $num): string

$bin = decbin($dec);
echo $bin;

出力結果は111110100となります。

8進数に変換

書式:decoct(int $num): string

$oct = decoct($dec);
echo $oct;

出力結果は764となります。

16進数に変換

書式:dechex(int $num): string

$hex = dechex($dec);
echo $hex;

出力結果は1f4となります。


今度は逆に変換してみましょう。

2進数から10進数に変換

書式:bindec(string $binary_string): int|float

$dec = bindec('111110100');
echo $dec; //500

続きを読む…»

401 views

PHPでPOSTリダイレクトする方法

PHPでリダイレクトさせたいとき、header関数を使いますよね。
通常はGETリクエストにてリダイレクトされます。
それを強制的にPOSTリクエストにし、パラメータを引き継ぐことができます。

headerの書式

header(string $header, bool $replace = true, int $response_code = 0): void

POSTリクエストでパラメータを引き継いでリダイレクトするには、$response_code307を与えます。

header("Location: example.php", true, 307);

公式マニュアル:
https://www.php.net/manual/ja/function.header.php

5,004 views

コールバック関数でスコープ外の変数を使う

配列の各要素に対して処理を行いたいとき、コールバック関数を使います。

コードの例を見ていきましょう。

$data = [ 1, 2, 3 ];

$data = array_map(function($i) {
    return $i * 2;
}, $data );

print_r($data);

出力結果

Array
(
    [0] => 2
    [1] => 4
    [2] => 6
)

次に、各要素に掛ける数値を外部で変数として宣言します。
それだけだとコールバック関数の中で使用することは出来ませんのでuseを使います。

$data = [ 1, 2, 3 ];
$n = 2;

$data = array_map(function($i) use ($n) {
    return $i * $n;
}, $data );

print_r($data);

同じ出力結果が得られます。

Array
(
    [0] => 2
    [1] => 4
    [2] => 6
)

他に2次元の連想配列に対して任意のデータを一括で追加することも出来ます。
続きを読む…»

1,089 views

null合体演算子

PHPでもPHP7からnull合体演算子がサポートされるようになりました。
よく使う場面としては、nullの場合は空の文字列を返したい等です。

$val = null;
echo $val ?? "default";

出力結果

default

その他、C#やSwiftでも使えます。
JavaScriptはES2020からサポートされるようになったようです。
※Swiftの場合は「nil合体演算子」と呼ばれます。

なお、Perl(5.10以降)ではnull合体演算子は//だったりするので、言語によって違いがあります。
各言語仕様をご確認ください。

ちなみにVisualBasicだとNz関数がそれに当たるんでしょうか。
CSVエクスポートでのテキストデータのNull値について ACCESS

305 views