Sibainu Relax Room

柴犬と過ごす

PHP 実行演算子の活用について

疲れることだ俺はもう寝るぞと言っている柴犬です。

概要

CSVファイルを読み込むところでUTF-8とShift_JISの判定ができないか考えてみました。

PHPには実行演算子がありOSのコマンドが実行できます。

ですので、実行演算子を触ってみることにします。

Shift_JIS を UTF-8 で出力

quick.php に手を加えます。

配列の入れ子を作るところで Shift_JIS から UTF-8 に変換するため要素毎に挿入します。

変更前

  $file = fopen($csvfile, 'r');
  $records = [];
  // 入れ子の配列を作成します
  while (($line = fgetcsv($file, 256, ',')) !== FALSE) {
    $records[] = $line;
  }
  fclose($file);

変更後

  $file = fopen($csvfile, 'r');
  $records = [];
  // 入れ子の配列を作成します
  while (($line = fgetcsv($file, 256, ',')) !== FALSE) {
    $line[0] = mb_convert_encoding($line[0], 'UTF-8', 'SJIS');
    $line[1] = mb_convert_encoding($line[1], 'UTF-8', 'SJIS');
    $records[] = $line;
  }
  fclose($file);

実行結果です。

UTF-8 を Shift_JIS で出力

これも同じく quick.php に手を加えます。

書き出す直前で UTF-8 から Shift_JIS に変換するため1行挿入します。

変更前

  // 配列を改行で繋いで一つの文字列にします
  $writecsv = implode("\n", $output);

変更後

  // 配列を改行で繋いで一つの文字列にします
  $writecsv = implode("\n", $output);
  $writecsv = mb_convert_encoding($writecsv, 'SJIS', 'UTF-8');

実行結果です。

csvファイルの文字セットの判定

Linux には、コマンドの中に file がありファイルに含まれるデータの種別を認識できます。

IBM Documentation の次の公式HPを見てみます。

https://www.ibm.com/docs/ja/aix/7.2?topic=f-file-command

ここには、次のようなことが書かれています。

-i フラグを使用すると、file を指定した各オペランドの識別に次の形式が使用されます。

"%s: %s¥n", file, type

file が キャラクター・スペシャル なら type は character special の文字列が含まれますとあります。

Ubuntu で実行してみました。

上がCSVファイルがUTF-8で、下がShift_JISの結果です。

charset に注目してみますと、utf-8 かたや unknown-8bit です。

ですので、サーバーが UNIX 系なら次のように実行演算子を使い条件分けをして処理することができます。

  $filepath = "";  
  $result = `file -i {$filepath}`;

  if !(mb_contains($result, 'text/csv') &&
       preg_match('/charset=[\w]+(-[\w]+)+/', $result, $data)) {
    return;
  }
  
  if count(data) > 0 {
    return;
  }

  if (mb_contains($data[0], 'utf-8') {
    // 処理文
  } else {
    // 処理文
  }  

実行演算子については、PHPの公式HPで記述があります。

https://www.php.net/manual/ja/language.operators.execution.php

そこの中に次の例の記述があります。

You can use variables within a pair of backticks (``).

<?php
    $host = 'www.wuxiancheng.cn';
    echo `ping -n 3 {$host}`;
?>

これを参考にして「独習PHP のp117 リスト3.26」変形して次のようなコードが書けます。

copy

<pre>
<?php
$mydir = __DIR__ . '\\';
$result = `dir {$mydir}`;
print mb_convert_encoding($result, 'UTF-8', 'SJIS');

実行演算子「`」の中でも変数展開が使えることを確かめてみます。

これを xampp を起動して実行(C:\xampp\htdocs\selfphp\chap03にあるphpファイルを実行)すると

想定通りの結果となりました。

実行演算子「`」の中でも変数展開できることが分かりました。

しかし、コマンド「file」はWindowsにはありませんので確かめようがありませんので、これまでとします。