Newsgroup: it.comp.www.php
Titolo: formattare una stringa (preparare query mySql)

dovrei creare una funzione banale..
data una stringa dovrei sostituire alcune ricorrenze nel formato :int con i
corrispondenti valori passati per argomento..
dall'esempio ne capirete l'esatto funzionamento e natura..
$query = 'SELECT * FROM table WHERE name = :1 AND pass = :3 ORDER BY :2';
richiamando la funzione con l'argomentazione..
('nome', 'stato', 'password')
vorrei ottenere come valore di ritorno una stringa..
"SELECT * FROM table WHERE name = 'nome' AND pass = 'password' ORDER BY
'stato'";
ho gia' creato e testato una mia versione della funzione, ma a dire il vero
non sono molto soddisfatto poiche' e' IMHO non abbastanza elegante..
voi come procedereste?
(naturalmente senza usare funzioni specifiche come oci etc.. ma usando
funzioni stringhe, espressioni regolari etc..)
grazie in anticipo, 
iuz
-- 
www.iuz-lab.info

'stato'";
Orribile:
function substquery($query)
{
        $args   = func_get_args();
        return preg_replace('/:([0-9]+)/e', '"\'" . AddSlashes($args[\1])
."\'"', $query);
}
...il fatto e' che a questo punto e' tremendamente simile alla printf()
:-)
Oppure:
function substquery()
{
        $query = 'SELECT * FROM table WHERE name = :1 AND pass = :3 ORDER
BY :2';
        $args   = func_get_args();
        array_unshift($args, ''); // Mi serve args[0]...
        return preg_replace('/:([0-9]+)/e', '"\'" . AddSlashes($args[\1])
."\'"', $query);
}
Leonardo
-- 
Avere studiato senza mettere in pratica e' inutile;
mettere in pratica senza avere studiato e' pericoloso.
                                                - Conphpucio

 }
[..]
questo codice non funziona correttamente.. pur correggendo gli errori di
distrazione ho valori di ritorno non coerenti..
ho fatto qualche errore io testando la funzione?
-- 
www.iuz-lab.info

 
www.iuz-lab.info

 password
[..]
mmh.. io avrei optato per un'altro metodo di login..
ma il mio problema e' incentrato sulla preparazione di una query (qualunque
essa sia) non su un login..
rileggendo il post iniziale capirai quale e' esattamente il mio quesito..
-- 
www.iuz-lab.info


non ti piace fare una cosa del genere ?
--
function getQuery($where,$order)
{
  $query="SELECT * from table WHERE 1 ";
  foreach($where as $value)
    $query.="and ".$value;
  $query.=" ORBER BY ".$order;
  return $query
}
$query=getQuery(array("nome='pippo'","pass='poppo'"),"'stato'");
--
altrimenti non ho capito il problema
ciao
Alesi_27

 $query=getQuery(array("nome='pippo'","pass='poppo'"),"'stato'");
[..]
questa funzione e' troppo specifica..
non devo creare una funzione che costruisca un determinato tipo di query ma
che sostituisca alla query i giusti valori..
ie.
SELECT :2 FROM :1 WHERE items = :3 GROUP BY :4
('table', 'category', 'item_name', 'date')
SELECT 'category' FROM 'table' WHERE items = 'item_name' GROUP BY 'date'
INSERT INTO :1 ('name', :2) VALUES (:3, :4)
('table', 'user', 'mark', 'Mark00')
INSERT INTO table ('name', 'user') VALUES ('mark', 'Mark00')
la query sara' accessibile all'interno della funzione, poiche' la stessa non
e' altro che un metodo di una classe dove la query e' una proprieta'..
-- 
www.iuz-lab.info

ho fatto qualche errore io testando la funzione?
Mah... mi verrebbe da dirti di si': se la chiamo con gli esatti argomenti
che hai fornito tu:
	$query = 'SELECT * FROM table WHERE name = :1 AND pass = :3 ORDER
BY :2';
        $ret   = substquery('nome', 'stato', 'password');
ottengo:
SELECT * FROM table WHERE name = 'nome' AND pass = 'password' ORDER BY
'stato'
che mi pare esattamente quello che volevi.
Di sicuro, almeno uno di noi due non si e' spiegato bene :-)... tanto per
cominciare, quali erano gli "errori di distrazione", e in che modo li hai
corretti?


 corretti?
[..]
si, avevo interpretato male il tuo codice ..
funziona bene.. ed anche se non mi piace molto usare eval e' pur sempre una
soluzione che non avevo valutato..
-- 
www.iuz-lab.info

 
adesso è più chiaro:
in modo "teorico" dovresti formalizzarti il linguaggio per creare una 
grammatica (tra l'altro puoi prendere spunto dalla grammatica di SQL), e 
poi ti scrivi una specie di parser che presa una stringa sia in grado di 
"smontarla" secondo la grammatica e effettuare le dovute operazioni.
Fai un gran lavoro ma ti ritrovi con la possibilità di fare realmente 
quello che vuoi sulla stringa.
In modo più semplice, con le espressioni regolari, ma non sò esserti di 
grande aiuto
ciao
Alesi_27

 "smontarla" secondo la grammatica e effettuare le dovute operazioni.
[..]
ho gia' creato una funzione che fa' tutto il necessario..
ma preferivo esaminare anche soluzioni non codate da me (visto che come
detto in precedenza non trovo detto codice abbastanza elegante)
-- 
www.iuz-lab.info



In alternativa, puoi usare preg_match per trovare tutte le sequenze di
":N" (sarebbe meglio IMHO ":NN:") e costruire un array di sostituzione
cosi':
function substquery()
{
        $query = 'SELECT * FROM table WHERE name = :1: AND pass = :3:
ORDER BY :2:';
        $args   = func_get_args();
	$repl	= array();
        array_unshift($args, ''); // Mi serve args[0]...
	foreach($args as $id => $value)
		$repl[":$id:"] = "'" . AddSlashes($value) . "'";
	return strtr($query, $repl);
}
Ho usato :1: invece di :1 perche', se hai dieci argomenti, indovina un
po' cosa succederebbe a ":10"... :-|
Leonardo Murphy


cosi':
Ehmmmm... il "cosi'" si riferisce alla versione villana, che non usa
affatto preg_match ma un brutale foreach :-)
Leonardo e le firme involontariamente appropriate


 Leonardo e le firme involontariamente appropriate
sto' elaborando un'altra grammatica a fronte di nuove necessita'..
ed entro domattina dovrei postare la nuova funzione..
mi farebbe piacere avere un secondo parere (il primo e' il mio) sulla
validita' della funzione che postero'..
-- 
www.iuz-lab.info

 Leonardo e le firme involontariamente appropriate
sto' elaborando un'altra grammatica a fronte di nuove necessita'..
ed entro domattina dovrei postare la nuova funzione..
mi farebbe piacere avere un secondo parere (il primo e' il mio) sulla
validita' della funzione che postero'..
comunque sia grazie
-- 
www.iuz-lab.info

 comunque sia grazie
dovresti comprenderne il funzionamento abbastanza facilmente..
sono molto ben accette critiche e consigli..
function ssqlf(){
 $query = 'SELECT * FROM table WHERE name = :n1 AND pass = :3 AND value
= :i4 AND value1 = :f5 ORDER BY :e2,:3';
 
 preg_match_all('/:([nife]*)(\d+)/', $query, $matches);
 $args = func_get_args();
 while (list($id, $val) = each($matches[0])) {
  if (!isset($replace[$val])) {
   switch ($matches[1][$id]) {
    case 'n': $replace[$val] = $args[$matches[2][$id] - 1]; break;
    case 'i': $replace[$val] = intval($args[$matches[2][$id] - 1]); break;
    case 'f': $replace[$val] = doubleval($args[$matches[2][$id] - 1]);
break;
    case 'e': default: $replace[$val] = "'" .
mysql_real_escape_string($args[$matches[2][$id] - 1]) . "'";
   }
  }
 }
 return strtr($query, $replace);
}
echo ssqlf('uno', 'due', 'tre', 55, '55dd');
-- 
www.iuz-lab.info

= :i4 AND value1 = :f5 ORDER BY :e2,:3';
Mi pare molto piu' flessibile dell'altra versione, ed e' anche piu'
potente, puoi validare gli argomenti.
Direi che stai convergendo verso una "sprintf col turbo" :-)
Un ottimo lavoro. L'unica perplessita' che mi resta e' che cosi' ti
tocca scrivere una ssqlf per ogni query; sarebbe piu' pratico se la
query fosse passata dall'esterno... magari usando un indice in modo
da limitarti alle query permesse.
Leonardo


 da limitarti alle query permesse.
[..]
no, la query non formattata viene memorizzata all'interno di una classe e
questa funzione si presentera' come metodo che prepara la query
formattandola in base agli argomenti passatigli..
grazie del giudizio cmq.. 
non ero sicuro di procedere nel modo piu' adatto..
-- 
www.iuz-lab.info