Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: SimpleXML, DOM xml, zostawia dziury po usunięciu plików
Forum PHP.pl > Forum > PHP
shpaque
Witam serdecznie,
nie mogę ogarnąć dość może kontrowersyjnej dla niektórych rzeczy, mianowicie normalnie i w innych przypadkach usuwając klucze z pliku xml funkcją poniżej, przy usunięciu ostatniej ladnie mi "biutifuje" plik, natomiast przy usuwaniu plików (i informacji o plikach w xml) zostawia dziury po usuniętych nodach:

  1. // Funkcja do upiększania formatu xml po jego zapisaniu
  2. function formatXml($simpleXMLElement) {
  3. $xmlDocument = new DOMDocument('1.0', 'utf-8');
  4. $xmlDocument -> preserveWhiteSpace = false;
  5. $xmlDocument -> formatOutput = true;
  6. $xmlDocument -> loadXML($simpleXMLElement -> asXML());
  7. return $xmlDocument -> saveXML();
  8. }


a tu cala klamerka

  1. // W tym kroku sprawdźmy, czy nie należy usunąć jakichś plików
  2. if (isset($postPage['files'])) {
  3. $postFiles = $postPage['files'];
  4. foreach ($postFiles as $key => $f) {
  5. $found = $loadPageDataBase -> xpath('files/file[@id = "'.$key.'"]'); // Szukamy w bazie danych klucza o tym atrybucie ID
  6. if (count($found) == 1) {
  7. if (isset($f['delete']) && $f['delete'] === (string)$found[0]['id']) {
  8. $fileToDelete = './db/upload/'.$found[0][0];
  9. if (file_exists($fileToDelete)) {
  10. // Usuwamy pozycję w bazie danych
  11. $dom = dom_import_simplexml($found[0]);
  12. $dom -> parentNode -> removeChild($dom);
  13. // Oraz usuwamy sam plik
  14. unlink($fileToDelete);
  15. }
  16. else {
  17. echo "<script>window.location.href='./admin.php?page=pages&edit=".$postPage['id']."&danger=Nie odnaleziono pliku ".$found[0][0]."!'</script>";
  18. }
  19. }
  20. else {
  21. // Aktualizujemy nazwy plików
  22. $found[0]['title'] = $postFiles[$key]['title'];
  23. }
  24. }
  25. else {
  26. echo "<script>window.location.href='./admin.php?page=pages&edit=".$postPage['id']."&danger=Nie odnaleziono pliku o id ".$key." w bazie danych!'</script>";
  27. }
  28. }
  29. }
  30.  
  31. // W tym kroku sprawdźmy, czy nie należy dodać jakichś plików
  32. ...
  33.  
  34.  
  35. $loadPageDataBase -> asXML($pathToPageToUpdate);
  36. // Układamy bazę na nowo (biutifujemy)
  37. $beautifyXML = htmlspecialchars(formatXml($loadPageDataBase));
  38. $beautifyXML = html_entity_decode($beautifyXML);
  39. $beautyFile = fopen($pathToPageToUpdate, 'w');
  40. flock($beautyFile, LOCK_EX);
  41. fwrite($beautyFile, $beautifyXML);
  42. flock($beautyFile, LOCK_UN);
  43. fclose($beautyFile);


generalnie cały problem polega na tym, że kiedy zostaja usuniete wszystkie pliki robi sie dziura:
- przyklad pierwszy - mam 5 plikow - usune 4 z nich, wszystko jest ok, jak usune ostatni (piaty) robi sie dziura jako jeden wiersze w pliku xml.
- przyklad drugi - mam 5 plikow, usune wszystkie 5 - robi sie dziurna na 5 wierszy w pliku xml (chyba ze w miedzyczasie dodam jakies pliki - to wypelnia ta dziure, np dodam 3 pliki, zostanie dziura na 2 wiersze...

@EDIT
Podejrzewam - mam pewność że chodzi o tą funkcję - znalazłem w necie, że jedni mówią żeby preservewhitespace było na false, inni true - generalnie nei ma to znaczenia bo zawsze przy usunieciu wszystkich dzieci konkretnego klucza zostają jakieś "\n" i stad nie zmienia się na "<rodzic/>" tylko zostaje "<rodzic </rodzic>" i TYLKO w przypadku usunięcia wszystkich choldren, czyli pozostawienia pustego rodzica...
trueblue
Zerknij na to: https://www.php.net/manual/en/libxml.constants.php#102279
shpaque
to zauwazylem, ale nie bardzo mi to cos pomaga, nawet na sztywno jak zrobilem to nadal zapisuja sie te biale znaki - byc moze problem jest w samym usunieciu dziecka z XPATH'a? no ale w sumie dopoki nie usunie sie ostatniego w rodzicu - wszystko jest w porzadku..
trueblue
Ale dodałeś tą flagę przy wczytywaniu do DOMDocument?
shpaque
tak, nawet zamienilem simplexml na domdocument i probowalem dodac i poznie jskasowac element na sztywno bez funkcjo ale nic sie nie zmienilo
trueblue
A jak to działa? Przeglądasz plik załadowany do $loadPageDataBase, a usuwasz węzły w innych plikach, które ładujesz odrębnie (dom_import_simplexml) na podstawie wartości węzłów z $loadPageDataBase.
shpaque
tak dzial ze napisalem sobie osobny php ze zdublowanym xml i zrobilem to samo co mam w duzej klamrze - czyli zaimportowalem domem plik, edytowalem go i zapisalem funkcja zmieniona z flagą. I dalej zostały mi dziury
trueblue
To może najpierw zacznij od uproszczenia kodu.
Do DOMDocument możesz załadować XML, możesz też wykonywać zapytania i możesz też usuwać węzły. Całość w ramach obsługi jednego obiektu.
Zobaczysz co wtedy otrzymasz.

https://kawalekkodu.pl/the-tag-is-out-there...domxpath-s01e01
https://kawalekkodu.pl/the-tag-is-out-there...domxpath-s01e03
shpaque
rozwiązałem problem w prosty znaleziony sposób - zmieniłem funkcję na:

  1. function saveBeautyXml($loadedXml, $pathToXml) {
  2. $dom = dom_import_simplexml($loadedXml) -> ownerDocument;
  3. $dom -> formatOutput = true;
  4. return $dom -> save($pathToXml);
  5. }


a zamiast $load... -> asXML(); i pozniej calego upiekszania pliku wystarczylo wywolanie tej funkcji, czyli calosc wyglada tak i dziala genialnie:

  1. ...
  2. // W tym kroku sprawdźmy, czy nie należy usunąć jakichś plików
  3. if (isset($postPage['files'])) {
  4. $postFiles = $postPage['files'];
  5. foreach ($postFiles as $key => $f) {
  6. $found = $loadPageDataBase -> xpath('files/file[@id = "'.$key.'"]'); // Szukamy w bazie danych klucza o tym atrybucie ID
  7. if (count($found) == 1) {
  8. if (isset($f['delete']) && $f['delete'] === (string)$found[0]['id']) {
  9. $fileToDelete = './db/upload/'.$found[0][0];
  10. if (file_exists($fileToDelete)) {
  11. // Usuwamy pozycję w bazie danych
  12. $dom = dom_import_simplexml($found[0]);
  13. $dom -> parentNode -> removeChild($dom);
  14. // Oraz usuwamy sam plik
  15. unlink($fileToDelete);
  16. }
  17. else {
  18. echo "<script>window.location.href='./admin.php?page=pages&edit=".$postPage['id']."&danger=Nie odnaleziono pliku ".$found[0][0]."!'</script>";
  19. }
  20. }
  21. else {
  22. // Aktualizujemy nazwy plików
  23. $found[0]['title'] = $postFiles[$key]['title'];
  24. }
  25. }
  26. else {
  27. echo "<script>window.location.href='./admin.php?page=pages&edit=".$postPage['id']."&danger=Nie odnaleziono pliku o id ".$key." w bazie danych!'</script>";
  28. }
  29. }
  30. }
  31.  
  32. // W tym kroku sprawdźmy, czy nie należy dodać jakichś plików
  33. if (isset($_FILES['uploads'])) {
  34. $filesToUpload = $_FILES['uploads'];
  35. $countFilesToUpload = count($filesToUpload['name']);
  36. $counter = 0;
  37. for ($i = 0; $i < $countFilesToUpload; $i++) {
  38. $newFileId = newStringId(8);
  39. $fileExtension = explode('.', $filesToUpload['name'][$i]);
  40. $fileExtension = strtolower(end($fileExtension));
  41. $fileName = str_replace('.'.$fileExtension, '', $filesToUpload['name'][$i]);
  42. if (in_array($fileExtension, $allowedExtensions)) {
  43. $newFile = $fileName.'.'.$fileExtension;
  44. $countWhile = 0;
  45. while (file_exists('./db/upload/'.$newFile)) {
  46. $countWhile++;
  47. $newFile = $fileName.'['.$countWhile.'].'.$fileExtension;
  48. }
  49. move_uploaded_file($filesToUpload['tmp_name'][$i], './db/upload/'.$newFile);
  50. // Dodajmy wpis do bazy danych
  51. $newFile = $loadPageDataBase -> files -> addChild('file', $newFile);
  52. $newFile -> addAttribute('id', $newFileId);
  53. $newFile -> addAttribute('title', '');
  54.  
  55. $counter++;
  56. }
  57. }
  58. }
  59. saveBeautyXml($loadPageDataBase, $pathToPageToUpdate);
To jest wersja lo-fi głównej zawartości. Aby zobaczyć pełną wersję z większą zawartością, obrazkami i formatowaniem proszę kliknij tutaj.
Invision Power Board © 2001-2025 Invision Power Services, Inc.