Pomoc - Szukaj - Użytkownicy - Kalendarz
Pełna wersja: [PHP] błędy w generowaniu csv
Forum PHP.pl > Forum > Przedszkole
neurogen
napisałem skrypt który z xml generuje csv i działa to dla większości z ponad 20.000 węzłów, ale niektóre wygenerowane linie csv są zepsute i nie mam pojęcia z jakiego powodu. wrzuciłem na hosting plik (ma 48mb ale widać w kilku miejscach te błędy gdy wyłączy się word wrap - nagle następuje przełamanie linii, albo jakiś notice) wynik
Neutral
Czy mógłbyś podać kod?
SmokAnalog
Zamiast podawać ogromny plik, który w dodatku być może zawiera wrażliwe dane, wysil się na wycięcie z niego jednej prawidłowej i jednej nieprawidłowej linii. I, jak kolega wyżej zasugerował, pokaż kod.
Pyton_000
Kod
<b>Notice</b>:  Trying to get property 'LastName' of non-object in <b>H:\xampp\htdocs\pubmed\csv.php</b> on line <b>71</b><br />
<br />
<b>Notice</b>:  Trying to get property 'ForeName' of non-object in <b>H:\xampp\htdocs\pubmed\csv.php</b> on line <b>73</b><br />


Jakieś notice...

Przełamania lini też są poprawne tylko Ty nie poprawnie generujesz CSV. Teksty powinny być ujęte w np. " wtedy przełamanie linni jest nie istotne.

KOD pokaż..
neurogen
link do skryptu zamieniającego xml (312mb) na csv. ładuje się 1-2min.
http://evidence-based-dentistry.org/csv.php
view-source:http://evidence-based-dentistry.org/csv.php

np.linie 24,918,4284


csv.php
  1. <?php
  2. $articles = simplexml_load_file('2017.xml');
  3. $id=27;
  4. foreach ($articles as $text):
  5.  
  6.  
  7. $title=$text->MedlineCitation->Article->ArticleTitle;
  8.  
  9. $postname = strtolower($title);
  10. $postname = str_replace(' ', '-', $postname);
  11. $postname = preg_replace('/[^0-9a-z\-]+/', '', $postname);
  12. $postname = preg_replace('/[\-]+/', '-', $postname);
  13. $postname = trim($postname,'-');
  14. $postname = substr($postname,0,200).'';
  15.  
  16. $abstract=$text->MedlineCitation->Article->Abstract->AbstractText;
  17.  
  18.  
  19. $author=$text->MedlineCitation->Article->AuthorList->Author;
  20. $journallowercase=$text->MedlineCitation->Article->Journal->Title;
  21. $journal = ucwords($journallowercase);
  22.  
  23. $year=$text->MedlineCitation->DateRevised->Year;
  24. $month=$text->MedlineCitation->DateRevised->Month;
  25. $day=$text->MedlineCitation->DateRevised->Day;
  26.  
  27. $pmid=$text->PubmedData->ArticleIdList->ArticleId;
  28.  
  29. #$tag1=$text->MedlineCitation->KeywordList->Keyword[0];
  30. #$tag2=$text->MedlineCitation->KeywordList->Keyword[1];
  31. #$tag3=$text->MedlineCitation->KeywordList->Keyword[2];
  32. #$tag4=$text->MedlineCitation->KeywordList->Keyword[3];
  33. #$tag5=$text->MedlineCitation->KeywordList->Keyword[4];
  34.  
  35. #$tag6=$text->MeshHeadingList->MeshHeading->DescriptorName;
  36.  
  37.  
  38. if (! empty($abstract)) {
  39. echo $id;#id
  40. echo "@";
  41. echo "1";#post_author
  42. echo "@";
  43. echo $year;
  44. echo "-";
  45. echo $month;
  46. echo "-";
  47. echo $day;
  48. echo "@";#post_date
  49. echo $year;
  50. echo "-";
  51. echo $month;
  52. echo "-";
  53. echo $day;
  54. echo " 12:00:00";#post_date_gmt
  55. echo "@";
  56.  
  57. echo "<div style='text-align:justify;'>";
  58. echo "<strong>Abstract:</strong> ";
  59. echo $abstract;#post_content
  60. echo "<br/><br/>";
  61. echo $journal;
  62. echo " - ";
  63.  
  64. echo $text->MedlineCitation->Article->AuthorList->Author[0]->LastName;
  65. echo " ";
  66. echo $text->MedlineCitation->Article->AuthorList->Author[0]->ForeName;
  67. echo ", ";
  68.  
  69. if (!empty($text->MedlineCitation->Article->AuthorList->Author[1]->LastName)) {
  70. echo $text->MedlineCitation->Article->AuthorList->Author[1]->LastName;
  71. echo " ";
  72. echo $text->MedlineCitation->Article->AuthorList->Author[1]->ForeName;
  73. echo ", ";
  74. }
  75. if (!empty($text->MedlineCitation->Article->AuthorList->Author[2]->LastName)) {
  76. echo $text->MedlineCitation->Article->AuthorList->Author[2]->LastName;
  77. echo " ";
  78. echo $text->MedlineCitation->Article->AuthorList->Author[2]->ForeName;
  79. echo ", ";
  80. }
  81. if (!empty($text->MedlineCitation->Article->AuthorList->Author[3]->LastName)) {
  82. echo $text->MedlineCitation->Article->AuthorList->Author[3]->LastName;
  83. echo " ";
  84. echo $text->MedlineCitation->Article->AuthorList->Author[3]->ForeName;
  85. echo ", ";
  86. }
  87. if (!empty($text->MedlineCitation->Article->AuthorList->Author[4]->LastName)) {
  88. echo $text->MedlineCitation->Article->AuthorList->Author[4]->LastName;
  89. echo " ";
  90. echo $text->MedlineCitation->Article->AuthorList->Author[4]->ForeName;
  91. echo ", ";
  92. }
  93. if (!empty($text->MedlineCitation->Article->AuthorList->Author[5]->LastName)) {
  94. echo $text->MedlineCitation->Article->AuthorList->Author[5]->LastName;
  95. echo " ";
  96. echo $text->MedlineCitation->Article->AuthorList->Author[5]->ForeName;
  97. echo " ";
  98. }
  99.  
  100. echo " - ";
  101. echo $day;
  102. echo "/";
  103. echo $month;
  104. echo "/";
  105. echo $year;
  106. echo " - ";
  107. echo "<a href='https://www.ncbi.nlm.nih.gov/pubmed/$pmid' target='_blank'>";
  108. echo $pmid;
  109. echo "</a>";
  110. echo "</div>";
  111.  
  112. echo "@";
  113. echo $title;#post_title
  114. echo "@";
  115. echo $abstract;#post_excerpt
  116. echo "@";
  117. echo "publish";#post_status
  118. echo "@";
  119. echo "open";#comment_status
  120. echo "@";
  121. echo "open";#ping_status
  122. echo "@";
  123. echo "";#post_password
  124. echo "@";
  125. echo $postname;#post_name
  126. echo "@";
  127. echo "";#to_ping
  128. echo "@";
  129. echo "";#pinged
  130. echo "@";
  131. echo $year;
  132. echo "-";
  133. echo $month;
  134. echo "-";
  135. echo $day;#post_modified
  136. echo "@";
  137. echo $year;
  138. echo "-";
  139. echo $month;
  140. echo "-";
  141. echo $day;
  142. echo " 12:00:00";#post_modified_gmt
  143. echo "@";
  144. echo "";#post_content_filtered
  145. echo "@";
  146. echo "0";#post_parent
  147. echo "@";
  148. echo "http://localhost/ebd/?p=$id";#guid
  149. echo "@";
  150. echo "0";#menu_order
  151. echo "@";
  152. echo "post";#post_type
  153. echo "@";
  154. echo "";#post_mime_type
  155. echo "@";
  156. echo "0";#comment_count
  157.  
  158.  
  159. echo "\n";
  160. $id++;
  161.  
  162. }
  163. else
  164. {
  165. echo "";
  166. }
  167.  
  168. endforeach;
  169.  
  170. ?>
Neutral
Podaj kod w formacie xml, a nie coś już wygenerowanego. OK, dobra już nic, nie zajrzałem do view-source.

Podaj tego jakiś wycinek, bo u mnie wywala błędy (warning).
SmokAnalog
PHP ma wbudowane funkcje do obsługi CSV, skorzystaj z nich. W Twojej wersji wystarczy, że coś ma wewnątrz znak @ i już masz błąd. Poza tym masz HTML w CSV? Na 99% coś źle kombinujesz.
neurogen
wstawiam html do csv i to działa (wordpress odczytuje to prawidłowo), choć pewnie można to zrobić inaczej i lepiej. w tekście nie ma znaków @ innych niż separatory kolumn bo są kasowane wcześniej przez php. pytanie mam tylko z czego wynikają te błędy. że brakuje ' lub " ?





bardzo proszę o pomoc w tym temacie.
SmokAnalog
Jeśli Author to normalna tablica, zamień sobie to:

  1. echo $text->MedlineCitation->Article->AuthorList->Author[0]->LastName;
  2. echo " ";
  3. echo $text->MedlineCitation->Article->AuthorList->Author[0]->ForeName;
  4. echo ", ";
  5.  
  6. if (!empty($text->MedlineCitation->Article->AuthorList->Author[1]->LastName)) {
  7. echo $text->MedlineCitation->Article->AuthorList->Author[1]->LastName;
  8. echo " ";
  9. echo $text->MedlineCitation->Article->AuthorList->Author[1]->ForeName;
  10. echo ", ";
  11. }
  12.  
  13. if (!empty($text->MedlineCitation->Article->AuthorList->Author[2]->LastName)) {
  14. echo $text->MedlineCitation->Article->AuthorList->Author[2]->LastName;
  15. echo " ";
  16. echo $text->MedlineCitation->Article->AuthorList->Author[2]->ForeName;
  17. echo ", ";
  18. }
  19.  
  20. if (!empty($text->MedlineCitation->Article->AuthorList->Author[3]->LastName)) {
  21. echo $text->MedlineCitation->Article->AuthorList->Author[3]->LastName;
  22. echo " ";
  23. echo $text->MedlineCitation->Article->AuthorList->Author[3]->ForeName;
  24. echo ", ";
  25. }
  26.  
  27. if (!empty($text->MedlineCitation->Article->AuthorList->Author[4]->LastName)) {
  28. echo $text->MedlineCitation->Article->AuthorList->Author[4]->LastName;
  29. echo " ";
  30. echo $text->MedlineCitation->Article->AuthorList->Author[4]->ForeName;
  31. echo ", ";
  32. }
  33.  
  34. if (!empty($text->MedlineCitation->Article->AuthorList->Author[5]->LastName)) {
  35. echo $text->MedlineCitation->Article->AuthorList->Author[5]->LastName;
  36. echo " ";
  37. echo $text->MedlineCitation->Article->AuthorList->Author[5]->ForeName;
  38. echo " ";
  39. }


Na to:

  1. echo implode(', ', array_map(function ($author) {
  2. return $author->LastName . ' ' . $author->ForeName;
  3. }, $text->MedlineCitation->Article->AuthorList->Author));
neurogen
dzięki to pewnie skróci kod ale raczej nie zlikwiduje błędów.
SmokAnalog
Nie mów hop smile.gif może naprawić, bo Twój błąd to odwoływanie się do nieistniejącego obiektu.
neurogen
<b>Warning</b>: array_map(): Argument #2 should be an array in <b>H:\xampp\htdocs\pubmed\csv.php</b> on line <b>106</b><br />
<br />
<b>Warning</b>: implode(): Invalid arguments passed in <b>H:\xampp\htdocs\pubmed\csv.php</b> on line <b>106</b><br />
SmokAnalog
Czyli to nie jest tablica, ale obiekt implementujący ArrayAccess. Ja bym poszedł w tym kierunku, żeby pozamieniać ten kod z wypisywaniem autorów na coś zgrabniejszego i bezpieczniejszego. Mogę Ci pomóc z ogarnięciem tego, jeśli mi powiesz gdzie mogę znaleźć tę bibliotekę.
neurogen
źródło xml jest tu xml a kod skryptu php tu php
SmokAnalog
Link do PHP nie działa.
neurogen
poprawka: txt
SmokAnalog
Spróbuj tego:

  1. echo implode(', ', array_map(function (SimpleXMLElement $author) {
  2. return $author->LastName . ' ' . $author->ForeName;
  3. }, ((array) $text->MedlineCitation->Article->AuthorList)['Author']));


Nie wiem jak zgrabniej zamienić SimpleXMLElement na tablicę dzieci, ta bilbioteka jest strasznie wkur*iająca.
neurogen
niestety te same błędy
SmokAnalog
U mnie błędów nie ma, ale prawdopodobnie korzystasz z innego pliku XML niż ja. W kodzie jest użyty 2017.xml, a wysłałeś mi 2018.xml.
neurogen
faktycznie nie zauważam błędów NOTICE ale te przełamania kodu nadal występują i nie wiem dlaczego. widać to w podglądzie strony np linia 24 view-source:http://evidence-based-dentistry.org/csv.php
SmokAnalog
Widocznie masz w danych znaki nowej linii. Te dane, jak już mówiłem, średnio nadają się do formatu CSV. Ale jak koniecznie chcesz pozostać przy CSV, to musisz trzymać się standardu. CSV pozwala na nowe linie w danych, ale pod warunkiem, że wartość jest zamknięta w delimiterze takim jak cudzysłów.

Czyli na przykład taka linia jest zła:

Kod
1,lubię
placki,2018-06-04


Ale taka już dobra:

Kod
1,"lubię
placki",2018-06-04


Oczywiście trzeba wtedy uważać na cudzysłowy wewnątrz cudzysłowów. Kolejny powód dlaczego nie powinno się robić na pałę echo dla uzyskania CSV, tylko używać fputcsv albo jakichś bibliotek do obsługi tego formatu.
neurogen
wszystko psują niepotrzebne łamania linii wewnątrz tekstu czyli \n i \r w <AbstractText>
jak to najszybciej usunąć?jakiś kod regex żeby pozbyć się łamań ale tylko w ramach abstracttext?
Pyton_000
Zacznij czytać to co się do Ciebie pisze....
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.