Check alle échte Black Friday-deals Ook zo moe van nepaanbiedingen? Wij laten alleen échte deals zien

[PHP] verschil multidimensionele arrays

Pagina: 1
Acties:

  • HaTe
  • Registratie: Mei 2007
  • Laatst online: 19:13

HaTe

haat niet

Topicstarter
Ik wil graag een xml feed die update, in mijn mysql database zetten, maar de database en de xml feed moeten wel gesynchroniseerd blijven.
Er moeten dus telkens records worden verwijderd en nieuwe toegevoegd worden.

Nu dacht ik dat het het beste de xml lokaal op kan slaan en dan deze bij de volgende update ga vergelijken met die van het web, maar ik weet niet hoe ik dan kan kijken wat er nieuw is en wat er oud is. Het verschil kan ik wel achterhalen:
PHP:
1
2
3
4
5
6
7
8
9
10
foreach($xml_web_items as $key => $item)
{
    $temp_web[$key] = $item['movie'];
}
foreach($xml_local_items as $key => $item)
{
    $temp_local[$key] = $item['movie'];
}

$dif = array_diff($temp_web, $temp_local);

Maar op deze manier weet ik alsnog niet wat er is weggehaald en wat er is bijgekomen. Ook laat array_diff de keys niet zien, die ik weer nodig zou hebben om de gegevens van de volledige array te achterhalen.

Op deze manier gaat het niet lukken en ik weet niet hoe wel. Wie kan helpen? Ik hoop dat het probleem duidelijk is.

WP: ME PUHZ-SW75YAA + ERST30D-VM2ED | Solar: 17x TSM-340-DE06M.08 (5780Wp ~6200kWh), Azimuth 179°, Hellingshoek: 34° | PC specs


  • supreme tweaker
  • Registratie: December 2002
  • Laatst online: 28-08 01:27
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?php 
foreach($xml_web_items as $key => $item) 
{ 
    $temp_web[$key] = $item['movie']; 
} 
foreach($xml_local_items as $key => $item) 
{ 
    $temp_local[$key] = $item['movie']; 
} 

foreach($temp_local as $key => $item){
    // check if key/value combo from web items exists in local items
    // if not
        // add to db
}

foreach($temp_web as $key => $item){
    // check if key/value combo from local items exists in web items
    // if not
        // remove from db
}


// write web items to local items (mochten deze buiten de database ook bestaan..)
?>


Edit: klein foutje aangepast. In principe is dit toch wat je wil? Of ik heb je niet begrepen, of je stelt een vraag die je zelf ook wel uit had kunnen vogelen..

[ Voor 20% gewijzigd door supreme tweaker op 11-04-2011 01:12 ]

Burp


  • HaTe
  • Registratie: Mei 2007
  • Laatst online: 19:13

HaTe

haat niet

Topicstarter
Zo zou het denk ik wel kunnen ja :) Ik ga er morgen mee aan de slag. Bedankt!

//edit
Ik denk dat je bedoelde dat $dif met $temp_local en met $temp_web vergeleken moet worden?

//edit 2
Ik had gedacht dat dit wel zou werken:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
foreach($xml_web_items as $key => $item)
{
    $temp_web[$key] = $item['movie'];
}
foreach($xml_local_items as $key => $item)
{
    $temp_local[$key] = $item['movie'];
}
$dif = array_diff($temp_web, $temp_local);


$array_add = array();
$array_remove = array();
foreach($temp_web as $key => $item)
{
    if(in_array($item['movie'], $dif))
        $array_add[] = $xml_web_items[$key];
}
foreach($temp_local as $key => $item)
{
    if(in_array($item['movie'], $dif))
        $array_remove[] = $xml_local_items[$key];
}


Maar ik krijg 2 lege arrays terug en $dif bevat wel items.. Waar zit de fout.. Het is laat, ik ga slapen!

[ Voor 104% gewijzigd door HaTe op 11-04-2011 01:31 ]

WP: ME PUHZ-SW75YAA + ERST30D-VM2ED | Solar: 17x TSM-340-DE06M.08 (5780Wp ~6200kWh), Azimuth 179°, Hellingshoek: 34° | PC specs


  • Patriot
  • Registratie: December 2004
  • Laatst online: 13:27

Patriot

Fulltime #whatpulsert

Je moet niet vergelijken met $dif, die array_diff moet gewoon weg uit je code.

  • Ventieldopje
  • Registratie: December 2005
  • Laatst online: 26-11 20:53

Ventieldopje

I'm not your pal, mate!

array_diff_key of array_diff_assoc moet je naar kijken denk ik ;) Anders moet je idd beide gaan loopen ;)

[ Voor 23% gewijzigd door Ventieldopje op 11-04-2011 02:33 ]

www.maartendeboer.net
1D X | 5Ds | Zeiss Milvus 25, 50, 85 f/1.4 | Zeiss Otus 55 f/1.4 | Canon 200 f/1.8 | Canon 200 f/2 | Canon 300 f/2.8


  • HuHu
  • Registratie: Maart 2005
  • Niet online
Dus de inhoud van de database moet altijd gelijk zijn aan de inhoud van de XML? Dan kun je toch bij het binnenhalen van een nieuwe XML de database te legen en deze opnieuw te vullen aan de hand van de nieuwe XML?

[ Voor 6% gewijzigd door HuHu op 11-04-2011 09:06 ]


  • DataGhost
  • Registratie: Augustus 2003
  • Laatst online: 19:17

DataGhost

iPL dev

Wellicht beter of makkelijker: INSERT ... ON DUPLICATE KEY UPDATE ...
Oh wacht, dan moet je de verwijderde items ook nog uit je database halen.

[ Voor 35% gewijzigd door DataGhost op 11-04-2011 09:14 ]


  • HaTe
  • Registratie: Mei 2007
  • Laatst online: 19:13

HaTe

haat niet

Topicstarter
Patriot schreef op maandag 11 april 2011 @ 01:44:
Je moet niet vergelijken met $dif, die array_diff moet gewoon weg uit je code.
Zo werkt het wel ja:
PHP:
1
2
3
4
5
6
7
8
9
10
foreach($temp_web as $key => $item)
{
    if(in_array($item['movie'], $temp_local))
        $array_add[] = $xml_web_items[$key];
}
foreach($temp_local as $key => $item)
{
    if(in_array($item['movie'], $temp_web))
        $array_remove[] = $xml_local_items[$key];
}

Alleen klopt er iets niet. $xml_local_items bevat 1739 items en $xml_web_items bevat er 1710. Maar $array_add bevat 43 records, terwijl $array_remove er geen bevat... $array_remove had er dus (43-29=) 14 moeten hebben of $array_add had er 29 moeten hebben (niks verwijderd).. Ik niet snappen!
$array_add en $array_remove zijn beide leeg.. $dif bevat 43 records.
Ventieldopje schreef op maandag 11 april 2011 @ 02:32:
array_diff_key of array_diff_assoc moet je naar kijken denk ik ;) Anders moet je idd beide gaan loopen ;)
Nee, aan die keys heb ik niks. In de xml staat niks unieks, behalve de 'movie'.
HuHu schreef op maandag 11 april 2011 @ 09:06:
Dus de inhoud van de database moet altijd gelijk zijn aan de inhoud van de XML? Dan kun je toch bij het binnenhalen van een nieuwe XML de database te legen en deze opnieuw te vullen aan de hand van de nieuwe XML?
Ja, dat heb ik ook overwogen, maar vind ik niet netjes.. Ook kost dat veel meer rekenkracht en is het langzamer en is de database even leeg, waardoor de items even niet beschikbaar zijn..

//edit
Ik heb het tijdelijk toch maar even zo gedaan :+
PHP:
1
2
3
4
5
6
7
8
9
/*clear old db*/
$sql = "TRUNCATE TABLE items";
if($db->sql_query($sql))
    echo "Gelukt!";
else
    echo "Mislukt!";

/*add items from xml*/
$db->sql_multi_insert('items', $xml_web_items);

Qua tijd merk je het denk ik nauwelijks dat de db even leeg is..

[ Voor 10% gewijzigd door HaTe op 11-04-2011 14:03 ]

WP: ME PUHZ-SW75YAA + ERST30D-VM2ED | Solar: 17x TSM-340-DE06M.08 (5780Wp ~6200kWh), Azimuth 179°, Hellingshoek: 34° | PC specs


  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 13:05

Janoz

Moderator Devschuur®

!litemod

HaTe schreef op maandag 11 april 2011 @ 13:51:
Ja, dat heb ik ook overwogen, maar vind ik niet netjes..
'Netjes' is subjectief. Je kunt beter je architectuur beslissingen af laten hangen van objectieve overwegingen.
Ook kost dat veel meer rekenkracht
Dat is absoluut niet automatisch zo. Bij een feed die juist veel veranderd kan het uitzoeken en vervolgens een verzameling delete, update en insert commando's sturen een stuk duurder zijn dan een simpele delete gevolgd door een enkel insert statement
en is het langzamer
Zie boven. Niet automatisch zo. Sowieso is de database over het algemeen een stuk sneller met data bewerkingen dan PHP
en is de database even leeg, waardoor de items even niet beschikbaar zijn..
Transacties gebruiken

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Verwijderd

Ik neem aan dat alle items in die xml een uniek id of iets dergelijks hebben? Gebruik die dan als key van je $temp_web en $temp_local arrays en gebruik array_diff om inserts en deletes te bepalen. Volgens mij werkt array_diff namelijk niet op multidimensionale arrays (correct me if i'm wrong).

PHP:
1
2
$inserts = array_diff_key($temp_web,$temp_local);
$deletes = array_diff_key($temp_local, $temp_web);

  • HaTe
  • Registratie: Mei 2007
  • Laatst online: 19:13

HaTe

haat niet

Topicstarter
Alleen 'movie' is uniek. Maar dat is een string van 160 karakters ofzo.

Maar ik ben gewoon voor het verwijderen en weer toevoegen van alles gegaan.

@Janoz: Ja, je hebt gelijk. Ik zal eens naar Transacties gaan kijken, dat ken ik niet.

[ Voor 23% gewijzigd door HaTe op 12-04-2011 18:41 ]

WP: ME PUHZ-SW75YAA + ERST30D-VM2ED | Solar: 17x TSM-340-DE06M.08 (5780Wp ~6200kWh), Azimuth 179°, Hellingshoek: 34° | PC specs


  • Guillome
  • Registratie: Januari 2001
  • Niet online

Guillome

test

Een film heeft niet een ID in de database??
Dude..

If then else matters! - I5 12600KF, Asus Tuf GT501, Asus Tuf OC 3080, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router


  • HaTe
  • Registratie: Mei 2007
  • Laatst online: 19:13

HaTe

haat niet

Topicstarter
In mijn database wel, maar in de xml die niet van mij is niet.
Dude..

WP: ME PUHZ-SW75YAA + ERST30D-VM2ED | Solar: 17x TSM-340-DE06M.08 (5780Wp ~6200kWh), Azimuth 179°, Hellingshoek: 34° | PC specs


  • Tsjilp
  • Registratie: November 2002
  • Niet online

Tsjilp

RS[I]ds

om te voorkomen dat je db tijdelijk leeg is, voeg je een veld deleted toe, die standaard op 0 staat.

Voor de update doe je een `UPDATE table SET deleted=1`
daarna een INSERT INTO () ON DUPLICATE KEY UPDATE deleted=0

Daarna doe je DELETE FROM table WHERE deleted=1

Raar... Is zo gek nog niet


  • StephanVierkant
  • Registratie: Mei 2003
  • Laatst online: 14:41
Wellicht ten overvloede: controleer wel of het ophalen van de XML goed gaat. Zou jammer zijn als je database een weekend leeg blijft als de XML tijdelijk offline is, verplaatst wordt of van opmaak verandert.

  • FragFrog
  • Registratie: September 2001
  • Laatst online: 11:39
Tsjilp schreef op woensdag 13 april 2011 @ 13:52:
om te voorkomen dat je db tijdelijk leeg is, voeg je een veld deleted toe, die standaard op 0 staat.

Voor de update doe je een `UPDATE table SET deleted=1`
daarna een INSERT INTO () ON DUPLICATE KEY UPDATE deleted=0

Daarna doe je DELETE FROM table WHERE deleted=1
Of je gebruikt een transactie zoals al eerder is voorgesteld B) Zie ook de voorbeelden bij commit, het stelt vrij weinig voor om op te zetten :)

[ Site ] [ twitch ] [ jijbuis ]


  • Guillome
  • Registratie: Januari 2001
  • Niet online

Guillome

test

Hoe werkt zoiets nou eigenlijk onder de motorkap?
Je kan hele tabellen legen, en updaten, met relaties etc. En dan commit voert ie alles daadwerkelijk uit, en zonder commit is het onaangetast. Maakt ie een duplicaat van de database om het daarop uit te voeren ofzo?
Want als je een COMMIT doet en dan insert, en dan update, dan pakt ie die insert ook mee.

If then else matters! - I5 12600KF, Asus Tuf GT501, Asus Tuf OC 3080, Asus Tuf Gaming H670 Pro, 48GB, Corsair RM850X PSU, SN850 1TB, Arctic Liquid Freezer 280, ASUS RT-AX1800U router

Pagina: 1