[PHP/MySQL] mysql_query wacht op resultaat?

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Rekcor
  • Registratie: Februari 2005
  • Laatst online: 05-09 21:08
Ik heb een MySQL-wrapper class die SQL-resultaten uit de db trekt mbv mysql_query / mysql_query

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
  /**
  * Find array of values from database
  * @param [string] sql query
  * @return [array]
  */
  function getArray($sql)
  {    
    $db_rs = mysql_query($sql, $this->getConnectionId());
    $num_fields = mysql_num_fields($db_rs);
    while ($row = mysql_fetch_array($db_rs, MYSQL_ASSOC))
    {
      for ($i = 0; $i < $num_fields; $i++)
      {
        $result[mysql_field_name($db_rs, $i)][] = $row[mysql_field_name($db_rs, $i)];
      }
    }
    return $result;


Nu heb ik een functie geschreven, die twee tabellen in mijn database synchroniseert. Stel je hebt een tabel 'automerken' en een tabel 'autos'. Autos zijn gekoppeld aan automerken met een kolom 'automerkId'.

Als je een automerk verwijdert uit de tabel 'automerken' (bijv. Opel), dan moeten alle autos van het merk Opel uit de tabel 'autos' verwijderd worden.

Mijn code ziet er als volgt uit:

PHP:
1
2
3
4
5
6
7
8
9
10
11
/* haal automerken op */
$aThisData = $oThisDbTable->getArray();

/* haal autos op */
$aSyncData = $oSyncDbTable->getArray();  

/* bereken het verschil tussen de twee arrays */
$aDifference= array_minus_array($aSyncData['automerkId'], $aThisData['ID']);

/* aDifference bevat nu de IDs van autos waarvan het merk niet meer in de tabel automerken staat */
$oSyncDbTable->deleteRows($aArrayMinusArray['difference']); //verwijder autos


Het probleem is dat er soms (en zonder enige reden, zo lijkt het) auto's verwijderd worden, waarvan het merk nog wel bestaat. Mijn vraag is dan ook: hoe zou dit komen?

Mijn hypothese

Wacht php totdat

PHP:
1
$aThisData = $oThisDbTable->getArray();


is uitgevoerd, voordat

PHP:
1
$aSyncData = $oSyncDbTable->getArray();


wordt uitgevoerd?

Het kost natuurlijk wat tijd om gegevens uit de database te halen, dus ik kan me voorstellen dat $aThisData of $aSyncData nog leeg is (omdat de db nog niet zijn resultaten heeft teruggeven) zodra ik het verschil bereken met de functie array_minus_array. Of is dat grote onzin?

Acties:
  • 0 Henk 'm!

  • Rekcor
  • Registratie: Februari 2005
  • Laatst online: 05-09 21:08
*schop*

Intussen heb ik het probleem omzeild, maar mijn vraag blijft staan: als je PHP een query op laat halen in een MySQL-database, wacht de code dan voordat die query binnen is?

Acties:
  • 0 Henk 'm!

  • Snake
  • Registratie: Juli 2005
  • Laatst online: 07-03-2024

Snake

Los Angeles, CA, USA

Je voert die code singlethreaded uit he, PHP kan onmogenlijk door omdat hij de data nodig heeft van de database, hij wacht dus echt eer ie de data heeft.

Going for adventure, lots of sun and a convertible! | GMT-8


Acties:
  • 0 Henk 'm!

  • Icelus
  • Registratie: Januari 2004
  • Niet online
Ja, mysql_query zal altijd wachten. Je kunt ook mysql_unbuffered_query gebruiken, die zal niet op de resultaten wachten.

Weet je zeker dat je code klopt? Als er bijvoorbeeld geen rijen zijn zal de functie getArray null teruggeven i.p.v. een array.

Developer Accused Of Unreadable Code Refuses To Comment


Acties:
  • 0 Henk 'm!

  • Rekcor
  • Registratie: Februari 2005
  • Laatst online: 05-09 21:08
Ok, PHP wacht dus altijd. Bedankt!

Intussen los ik alles op m.b.v. 1 query.

Acties:
  • 0 Henk 'm!

  • HuHu
  • Registratie: Maart 2005
  • Niet online
Als je in je MySQL tabel een foreign key aangeeft en vervolgens ook nog de ON DELETE CASCADE gebruikt, dan kan je door simpelweg het automerk te verwijderen automatisch alle auto's meenemen.

En omdat PHP regel-voor-regel wordt uitgevoerd wordt er altijd gewacht totdat de vorige regel klaar is. De volgende regel kan zich immers baseren op gegevens uit de huidige regel die nog uitgevoerd wordt.

Acties:
  • 0 Henk 'm!

  • Rekcor
  • Registratie: Februari 2005
  • Laatst online: 05-09 21:08
HuHu schreef op dinsdag 13 maart 2007 @ 20:04:
Als je in je MySQL tabel een foreign key aangeeft en vervolgens ook nog de ON DELETE CASCADE gebruikt, dan kan je door simpelweg het automerk te verwijderen automatisch alle auto's meenemen.

En omdat PHP regel-voor-regel wordt uitgevoerd wordt er altijd gewacht totdat de vorige regel klaar is. De volgende regel kan zich immers baseren op gegevens uit de huidige regel die nog uitgevoerd wordt.
Bedankt voor de tip! Ik doe het nu met een DELETE + subquery (en laat het ook liever zo, want als de database ook nog op eigen houtje dingen gaat zitten uitvoeren, wordt mijn code helemaal onoverzichtelijk :+ )

Acties:
  • 0 Henk 'm!

  • HuHu
  • Registratie: Maart 2005
  • Niet online
Je code wordt er juist overzichtelijker door. Een query die allerlei vage DELETE's doet is toch echt lelijker dan een nette query met 1 DELETE, waarbij eventuele verwijzingen automatisch worden verwijderd :P.

Eventueel zet je er nog in commentaar boven dat de nutteloze, dode data middels CASCADE wordt verwijderd.

Acties:
  • 0 Henk 'm!

  • Icelus
  • Registratie: Januari 2004
  • Niet online
N.B. dit werkt alleen indien het om een InnoDB-type tabel gaat.

Developer Accused Of Unreadable Code Refuses To Comment


Acties:
  • 0 Henk 'm!

  • Rekcor
  • Registratie: Februari 2005
  • Laatst online: 05-09 21:08
HuHu schreef op dinsdag 13 maart 2007 @ 20:59:
Je code wordt er juist overzichtelijker door. Een query die allerlei vage DELETE's doet is toch echt lelijker dan een nette query met 1 DELETE, waarbij eventuele verwijzingen automatisch worden verwijderd :P.

Eventueel zet je er nog in commentaar boven dat de nutteloze, dode data middels CASCADE wordt verwijderd.
Misschien wordt de code er wel overzichtelijker door, maar het 'overall principe' van mijn programma niet.

Ik vind dat de database zo dom mogelijk moet zijn: data opslaan, data retrieven. De programmeertaal (in dit geval) doet al het 'denkwerk', HTML toont alles op het scherm.
Pagina: 1