Newsgroup: it.comp.www.php
Titolo: Ciclo su DB?

Salve ragazzi,
sto spulciando questo newgroup (ed altre fonti) alla ricerca della soluzione
ad un mio quesito che ho da diverso tempo.
Passo subito ad esporre il problema con un esempio, sperando di riuscire a
farmi capire.
Ipotizziamo di avere la struttura di un sito all'interno di una tabella del
dababase;
tralasciando i campi non importanti per l'esempio, abbiamo 3 campi: id,
titolo, parent;
l'id, inutile dirlo, si auto incrementa; il titolo è il nome della pagina;
il parent indica l'id della pagina padre dalla quale, nella struttura del
sito, la pagina in questione dipende.
ecco un esempio di qualche campo:
id        parent            titolo
1            0                informatica
2            1                portatile
3            2                configurazioni
4            3                posta elettronica
5            4                outlook express
costruendo la struttura del sito quindi avremo:
0 - Homepage
   |_ 1 - informatica
        |_ 2 - portatile
            |_ 3 - configurazioni
                |_ 4 - posta elettronica
                     |_ 5 - outlook express
Il mio problema è che, partendo ad esempio dal record "outlook express",
devo controllare se il valore di un campo booleano è true o false a ritroso,
su tutto il ramo dell'albero dal quale "outlook express" deriva.
Per spiegarmi meglio, ipotizziamo che la tabella contiene un 4° campo
"filtro" che, se impostato a true, impedisce la visualizzazione della
pagina; se viene inibito l'accesso all'area del sito "configurazioni", deve
essere chiusa logicamente anche tutta la parte del sito che ne deriva,
quindi "posta elettronica" e "outlook express":
 non mi basta dunque controllare se è true il valore di "outlook express",
ma il check dev'essere esteso a ritroso sulla struttura del ramo.
Come posso raggiungere tale obiettivo? sono mesi che questo dubbio mi
assale, ma ora ho l'estrema necessità di trovare una soluzione.
Vi ringrazio a tutti per la collaborazione!!!
In caso di risposte via email, togliete la parte in maiuscolo da mio
indirizzo.
Grazie!!!

 struttura del sito, la pagina in questione dipende.
[cut]
Salve,
il problema esposto e' tipico delle strutture ad albero (o categorie)
Esistono varie soluzioni al problema.
La piu' semplice e' quella di utilizzare XML al posto di un databse 
relazionale. Con XPath e' possibile fare quello che chiedi con una riga 
di codice. Il problema potrebbe riguardare la gestione sincronizzata 
delle operazioni in scrittura.
Un'altra possibilita' riguarda la gestione con una tabella di supporto 
non normalizzata su cui scrivere tutti i figli e sottofigli di un certo 
nodo. In questo modo e' possibile fare una ricerca in profondita' con 
una singola query. Il problema in questo caso non riguarda la scrittura 
o l'aggiunta/rimozione dei nodi bensi' la possibilita' di gestire lo 
spostamento dei nodi. In questo caso dovrebbe essere necessario 
eliminre tutti i sottonodi e ricrearli. Per il momento non ho 
approfondito alla ricerca di un algoritmo per gestire questo problema, 
ma se ne puo discutere.
Spero di esserti stato utile.
Saluti.


Non ne avevo sentito parlare, ma sto guardando ora le informazioni su Xpath;
sembra interessante, viene gestito come un file system. Hai la possibilità
di indirizzarmi su come mettere in pratica il mio caso?
da quello che ho capito, dovrei creare un xml in questo modo:
<?xml version="1.0" encoding="ISO-8859-1"?>
<pagine>
  <id num="1">
    <titolo>Informatica</titolo>
    <parent>0</parent>
  </id>
  <id num="2">
    <titolo>Portatile</titolo>
    <parent>1</parent>
  </id>
  <id num="3">
    <titolo>configurazioni</titolo>
    <parent>2</parent>
  </id>
  <id num="4">
    <titolo>posta elettronica</titolo>
    <parent>3</parent>
  </id>
  <id num="5">
    <titolo>outlook</titolo>
    <parent>4</parent>
  </id>
</pagine>
ora quale sarebbe la semplice riga di codice di cui mi parlavi?? ;-)
Grazie infinite!!!!

   </id>
[cut]
facendo dei ragionamenti, sono giunto alla conclusione che forse la
struttura che ho ipotizzato prima non è corretta per raggiungere lo scopo
prefissato, in quanto è semplicemente la "traduzione" del database; credo
invece che il file xml dovrebbe essere strutturato esattamente come un
filesystem ossia gerarchicamente; nel senso che "portatile" non dev'essere
sullo stesso livello di "informatica" come ho ipotizzato prima, ma DENTRO;
così come "configurazioni" e cosi via...
Sono sulla strada giusta? ;-)
TNX!!!!!

su tutto il ramo dell'albero dal quale "outlook express" deriva.
beh, supponendo che parti dall'elemento $HTTP_GET_VARS[id] e che il
valore booleano si chiama "flag", basta un ciclo di questo tipo:
$result=mysql_query("
SELECT * FROM tabella WHERE id=$HTTP_GET_VARS[id]",$database) 
or die("1".mysql_error());
res=mysql_fetch_object($result);
$parent=$res->parent;
# ora il flag e' in $res->flag
while ($parent!=0):
		$result2=mysql_query("
		SELECT * FROM tabella WHERE id=$parent",$database) 
		or die("2".mysql_error());
		$res2=mysql_fetch_object($result2);
		$parent=$res2->parent;
		# ora il flag e' in $res2->flag;
endwhile;
hola
Buttha

res=mysql_fetch_object($result);
e'
$res=mysql_fetch_object($result);

 ho ipotizzato prima, ma DENTRO; cosl come "configurazioni" e cosi via.
La conversione da db ad XML "corretta" sarebbe:
<?xml version="1.0" encoding="ISO-8859-1"?>
<pagine>
	<ids>
		<id num="1">
			<titolo>Informatica</titolo>
			<filtrato>0</filtrato>
			<ids>
				<id num="2">
					<titolo>Portatile</titolo>
					<filtrato>0</filtrato>
				</id>
				<id num="3">
					<titolo>configurazioni</titolo>
					<filtrato>1</filtrato>
					<ids>
						<id num="4">
							<titolo>posta elettronica</titolo>
							<filtrato>0</filtrato>
						</id>
						<id num="5">
							<titolo>outlook</titolo>
							<filtrato>0</filtrato>
						</id>
					</ids>
				</id>
			</ids>
		</id>
	</ids>
</pagine>
Una implementazione in php di XPath la trovi a
http://sourceforge.net/projects/phpxpath/
Caricando l'XML in un oggetto XPath, e possibile accedere a tutti i 
nodi con una istruzione del tipo "//id[@num=5]"
Poi e' sufficiente scorrere l'albero all'indietro e verificare i nodi 
parent.
Saluti.

Ringrazio vivamente entrambi per il vostro contributo!!
Ho provato lo script di Buttha e ha risolto alla grande il mio problema,
grazie infinite!!
Però la soluzione di Setec mi ha aperto nuovi orizzonti ed ora sono davvero
curioso di applicare i suoi consigli con phpxpath. Quello che mi chiedo a
questo punto è: quale delle due soluzioni sarebbe la più efficace? ci sono
pro e contro utilizzando una soluzione a discapito dell'altra? Xpath
comunque è qualcosa di notevole degno di un approfondimento. Grazie per
avermelo fatto conoscere!!
Saluti!

 su tutto il ramo dell'albero dal quale "outlook express" deriva.
Esiste un altro modo per rappresentare gli alberi in un 
RDBMS, che sfrutta quello che i db relazionali fanno meglio: 
trattare su insiemi.
La rappresentazione si basa insiemi annidati ed e' stata 
trattata in maniera sistematica in un libro e in vari 
articoli da Joe Celko; tanto che spesso tale 
rappresentazione e' chiamata con il suo nome oppure come 
"Joe Celko's nested sets". 
Cercando su google puoi trovare parecchio materiale.
-- 
Roberto Lupi

ma il check dev'essere esteso a ritroso sulla struttura del ramo.
Dato che il controllo e' true-bound, puoi fare cosi':
function checkFlag($conn, $id)
{
	$parent = 42;
	while($parent)
	{
		// if (!isset($GLOBALS['idcache'][$id]))
		// {
		$res=mysql_query("SELECT flag, parent FROM tabella 
WHERE id=$id,$conn);
		// $GLOBALS['idcache'][$id] = mysql_fetch_array($res);
		// // Cancellare questa riga e quella sotto
		list($flag, $id) = mysql_fetch_array($res);
		mysql_free($res);
		// }
		// list($flag, $id) = $GLOBALS['idcache'][$id];
		if ($flag)
			return true;
	}
	return false;
}
Se devi fare un mucchio di controlli puoi pensare a un caching (versione
commentata).
Leonardo