PHP / RegEx-テーブル名の前に付けるためのロジック
質問
だから、適切なテーブルプレフィックス(たとえば<!> quot; t。<!> quot;または<!> quot; r。<!> quot;を有効な列名に自動的に追加するスクリプトを作成しようとしています。 )
$t_columns = array('id', 'name', 'label');
$r_columns = array('related_value');
入力:
id > 1 AND (name = 'Hello' OR label IN ('World', 'Planet name AND label')) AND (related_value > 1 AND related_value < 50)
出力:
t.id > 1 AND (t.name = 'Hello' OR t.label IN ('World', 'Planet name AND label')) AND (r.related_value > 1 AND r.related_value < 50)
通常の str_replace を実行できないことに注意してください。すべてのテーブル名が適切に追加されるようにするための最も単純なコードは何でしょうか( preg_replace と推測されます)?
解決
これは多くの方法で、また正規表現を使用して行うことができます。私は個人的に配列アプローチを使用します。まず、この方法でマングリングテーブルを定義します。
$table = array(
'id' => 't.id',
'name' => 't.name',
'label' => 't.label',
'related_value' => 'r.related_value'
);
これにより、str_replace()呼び出しが非常に簡単になります。
function mangling(&$v, $k, $table)
{
if (($k & 1) == 0)
$v = str_replace(array_keys($table), array_values($table), $v);
}
$spans = explode("'", ' ' . $input);
array_walk($spans, 'mangling', $table);
$output = implode("'", $spans);
他のヒント
数秒考えた後、私はどのように取り組むかを示します:
文字を文字ごとにウォークスルーし、単一引用符を探しますが、エスケープされた文字をスキップします。 2つのエスケープされていない一重引用符(つまり、文字列)の間のものは一意のトークンに置き換えられ、そのトークンをキーとして、元の文字列を値として連想配列に入れられます。
文字列が邪魔になったので、既知の列名に対してstr_replace()
(またはpreg_replace()
)を実行します。おそらく、テーブルのエイリアスをキーとして、値を列名を含む列挙型配列として、連想配列に列名を構築します。これにより、交換を自動化できます。
テーブル名が入力されたら、トークンに対して<=>を実行し、元の文字列を元の場所に戻すだけで完了です。
このすべてを1回のヒットで実行するために、誰かが超素晴らしい(そしておそらく保守不能な)正規表現を鞭打つかもしれないと確信しています。しかし、正規表現が実際に適切なツールである場合にのみ正規表現を使用することを好みます。CFLがより適している場合ではありません。
ここで正規表現が良いアイデアかどうかわかりません。 PHPで検証を自分で実行するには、計算量を最小限に抑えるだけの価値があると思います。その後、データベースに変更が必要になった場合、正規表現の堅牢性を高める方法について心配する必要はありません。
Jamie Zawinskiがかつて言ったように、<!> quot;問題に直面したとき、「知っている、正規表現を使う」と思う人もいます。現在、2つの問題があります。 <!>引用;
適切なデータベースで作業していることを確認するワークフローを作成するという観点から、オブジェクト指向のアプローチを検討します。 TおよびRテーブルのクラスは、正規表現ではなく、同じメソッド内の条件付きロジックを使用して正しいテーブル型オブジェクトを構築するモデルクラスの子としてインスタンス化できます。