3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

知らないPHP解読の手順

Last updated at Posted at 2024-11-07

PHPを読むことを諦める瞬間

昔のPHPのコードはなぜか読みにくい。
Laravelが出る前の「フレームワーク乱立」が原因の1つではあるんですが、

それ以外に、
「これって、このフレームワーク独自の書き方なのか…?」と思ったら、
コーディング規約が(ない・古い・ゆるい)だけだったりします。

「僕の知ってるPHPじゃない」が結構ある

Laravel とか Symfony を見た後に、それ以外のフレームワークを見ると
抽象化されてないので、native な PHP という印象を受ける事があります。

知らないPHPフレームワークのコードをいざ読む時、
まず何からやったら良いのか、わからなくないですか?
例えば、こんな感じのPHPが書かれてるとします。

例文

$param = [':user_id' => Yii::$app-> users -> user_id];
$query = "SELECT COUNT(*) FROM user_log WHERE mid = :user_id";
$count = Yii::$app->db_component->createCommand($query, $param)->queryScalar() ?: 0;

3行くらいならまだ読めるんですが、これが100行続いてると
「もう読めない」となってきます。そういう時の、地道な解決策です。

(1)とにかくバラしてみる

メソッドチェーンも、コンポーネントを変数に代入しておくと、読んで理解できます。
三項演算子も、わざわざ省略しないで書いてみました。

$userComponent = Yii::$app->users;
$userId = $userComponent->user_id;

$param = [':user_id' => $userId];
$query = "SELECT COUNT(*) FROM user_log WHERE mid = :user_id";
$dbComponent = Yii::$app->db_component;
$command = $dbComponent->createCommand($query, $param);

$count = $command->queryScalar();
$count = ($count !== null && $count !== false) ? $count : 0;

(2)とにかく改行する

配列の代入がわかりますし、SQLもっと長い場合適切に改行することでSQLが読めるようになります。

$userComponent = Yii::$app->users;
$userId = $userComponent->user_id;

$param = [
    ':user_id' => $userId
];

$query = "
    SELECT 
        COUNT(*) 
    FROM 
        user_log 
    WHERE 
        user_id = :user_id
";

$dbComponent = Yii::$app->db_component;

$command = $dbComponent->createCommand($query, $param);

$count = $command->queryScalar();
$count = ($count !== null && $count !== false) ? $count : 0;

(3)とにかく説明を書いてみる

データ型もちゃんと分かるように書いてみる。

/** @var UserComponent $userComponent */
$userComponent = Yii::$app->users;

/** @var int|string|null $userId */
$userId = $userComponent->user_id;

// パラメータを個別に変数へ
$param = [
    ':user_id' => $userId
];

// SQLクエリを作成、確認しやすいようにフォーマット
$query = "
    SELECT 
        COUNT(*) 
    FROM 
        user_log 
    WHERE 
        user_id = :user_id
";

// DBコンポーネントを取得し変数に代入
/** @var DbComponent $dbComponent データベースコンポーネントインスタンス */
$dbComponent = Yii::$app->db_component;

// createCommandメソッドを使ってコマンドを作成
/** @var \yii\db\Command $command SQLコマンドオブジェクト */
$command = $dbComponent->createCommand($query, $param);

// queryScalarメソッドの結果を取得し、nullをチェックして0をデフォルトに設定
/** @var int|string|false|null $count COUNT結果の型 */
$count = $command->queryScalar();
$count = ($count !== null && $count !== false) ? (int)$count : 0;

(4)ORMに変換してみる

ORMに慣れてる人であれば、ORMで書き直したほうがわかりやすい。
どうやらこのフレームワークには、Eloquent的なライブラリがあるらしい。

use app\models\UserLog;

$userComponent = Yii::$app->users;

$userId = $userComponent->user_id;

$count = UserLog::find()
    ->where(['user_id' => $userId])
    ->count();

見比べてみよう

当初は、「これ $count ってことは int で返るよな…?」と半信半疑でしたが

$count = Yii::$app->db_component->createCommand($query, $param)->queryScalar() ?: 0;

説明を付けることで int で返っている事が、わかりますし

// queryScalarメソッドの結果を取得し、nullをチェックして0をデフォルトに設定
/** @var int|string|false|null $count COUNT結果の型 */
$count = $command->queryScalar();
$count = ($count !== null && $count !== false) ? (int)$count : 0;

ORMの方が何をやってるのか分かりやすい、気がします。

$count = UserLog::find()
    ->where(['user_id' => $userId])
    ->count();

理解できたら、書き直せる範囲で書き直す

もし書き直して良ければ書き直します。

古い書き方

$param = [':user_id' => Yii::$app-> users -> user_id];
$query = "SELECT COUNT(*) FROM user_log WHERE user_id = :user_id";
$count = Yii::$app->db_component->createCommand($query, $param)->queryScalar() ?: 0;

Yii の Active Record

use app\models\UserLog;
$userId = Yii::$app->users->user_id;
$count = UserLog::find()->where(['user_id' => $userId])->count() ?: 0;

もしも Laravel の Eloquent に置き換えるとしたらこうなる。

use App\Models\UserLog;
$userId = auth()->user()->id;
$count = UserLog::where('user_id', $userId)->count() ?: 0;

結論

今更 Laravel に置き換えるのかどうかは別として、昔の古いPHPのコードは読んでみたら
実は、ほとんど今とやってる事は変わってない事がわかります。

「ちゃんとチューニングしてある」っていう見方もあるんですが、
コードを読み解く工夫が必要な時点で、開発体験が悪くなるので、
こまめなアップデート、もしくは大胆なリプレイスが必要と、個人的には考えています。

3
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
3
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?