Pergunta

Então, eu estou tentando construir um script que automagicamente prepends nomes de coluna válido com seu prefixo tabela apropriada (por exemplo, "t." Ou "r".)

$t_columns = array('id', 'name', 'label');
$r_columns = array('related_value');

ENTRADA:

id > 1 AND (name = 'Hello' OR label IN ('World', 'Planet name AND label')) AND (related_value > 1 AND related_value < 50)

SAÍDA:

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)

Observe como você não pode fazer um normal de str_replace . Qual seria o código mais simples (Eu estou supondo preg_replace ) para garantir que todos os nomes de tabelas são devidamente anexado?

Foi útil?

Solução

Isto pode ser feito em uma série de maneiras, e também usando regex. Eu pessoalmente uso uma abordagem matriz. Primeiro de tudo, eu definir a tabela deturpação desta maneira:

$table = array(
    'id' => 't.id',
    'name' => 't.name',
    'label' => 't.label',
    'related_value' => 'r.related_value'
);

Isso vai fazer muito mais fácil o str_replace () chamada:

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);

Outras dicas

Depois de pensar de alguns segundos, aqui está como eu enfrentá-lo:

Passeio pela corda, char por char, procurando aspas simples, mas a ignorar os caracteres sobre escaparam. O material entre duas aspas simples unescaped (ou seja, as cordas) seria substituído com um token único, e colocado em uma matriz associativa, com aquele sinal como a chave, ea string original como o valor.

Agora que temos as cordas fora do caminho, fazer um str_replace() (ou preg_replace(), se você insistir) para os nomes das colunas conhecidos. Eu provavelmente construir os nomes de coluna em uma matriz associativa, com o nome alternativo de mesa como a chave, e o valor como uma matriz numérica contendo os nomes das colunas. Desta forma, a substituição pode ser automatizado.

Uma vez que os nomes de tabelas são preenchidos, basta fazer uma str_replace() para os tokens, para substituir as cordas originais de volta a seus lugares, e você está feito.

Eu tenho certeza que alguém poderia chicote um regexp super-impressionante (e provavelmente ao lado unmaintainable) para fazer tudo isso em uma batida. Mas eu prefiro usar regexps apenas em situações em que as expressões regulares são, na verdade, a ferramenta certa, não onde um CFL seria mais adequado.

Eu não sei se uma expressão regular é uma boa idéia aqui. Eu diria que valeria a pena a quantidade mínima de maior complexidade computacional para realizar a validação se em PHP. Então, se o seu banco de dados requer alterações, você não tem que puxar seu cabelo para fora se preocupar com a forma de aumentar a robustez da sua expressão regular.

Como Jamie Zawinski uma vez disse: "Algumas pessoas, quando confrontado com um problema, pense 'eu sei, eu vou usar expressões regulares.' Agora eles têm dois problemas. "

Em termos de criação de um fluxo de trabalho que irá certificar-se que você está trabalhando no banco de dados certo, eu consideraria tendo uma abordagem orientada a objetos. Aulas para T e mesas R pode ser instanciado filhos de uma classe de modelo responsável por construir o objeto do tipo tabela correta usando a lógica condicional dentro do mesmo método, em vez de uma regex.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top