Witaj Gościu! ( Zaloguj | Rejestruj )

Forum PHP.pl

 
Reply to this topicStart new topic
> [PHP]Baaardzo dziwny problem, VertrigoServ, Kod inaczej wykonuje się na domowym komputerze, a inaczej na serwerze?
robert-s
post 26.06.2012, 21:45:31
Post #1





Grupa: Zarejestrowani
Postów: 17
Pomógł: 1
Dołączył: 24.05.2012

Ostrzeżenie: (0%)
-----


Jak to jest w ogóle możliwe? co_jest.gif Kod pochodzi z tego miejsca: http://www.progresowi.pl/2011/10/26/robimy-mieszarke.html Jest to mieszarka synonimów.

  1. <?php
  2. class SEOMixer
  3. {
  4. public $input;
  5. public $output;
  6. public $limit = 1;
  7. private $braces = array("{", "}");
  8. private $delimiter = "|";
  9. function __construct($input)
  10. {
  11. $this->input = $input;
  12. }
  13. function mixAll()
  14. {
  15. $this->output = $this->input;
  16. while (strpos($this->output, $this->braces['1']) !== false)
  17. {
  18. $closed = strpos($this->output, $this->braces['1']);
  19. $substr = substr($this->output, 0, $closed + 1);
  20. $from = strrpos($substr, $this->braces['0']);
  21. $substr = substr($substr, $from);
  22. $_substr = $this->mixText($substr);
  23. $this->output = str_replace($substr, $_substr, $this->output);
  24. $substr = "";
  25. $_substr = "";
  26. }
  27. return;
  28. }
  29. function mixText($text)
  30. {
  31. $text = str_ireplace($this->braces, "", $text);
  32. $elements = explode($this->delimiter, $text);
  33. return $elements[array_rand($elements)];
  34. }
  35. function mix()
  36. {
  37. $this->mixAll();
  38. return $this->output;
  39. }
  40. }
  41. //tylko to dopisałem ja
  42. $tekst_do_mieszania = '{jakieś|{synonimy|zagnieżdżone}}';
  43. $mieszarka = new SEOMixer($tekst_do_mieszania);
  44. $text_wymieszany = $mieszarka->mix();
  45. echo $text_wymieszany;
  46. ?>


Problem dotyczy bardzo długich tekstów z zagnieżdzonymi synonimami, przy krótkich wydaje się że jest ok. Mój ma 86188 znaków, jest w nim 100 zdań i losuje się jedno z nich. Dodatkowo każdy wyraz ma synonimy. Po wysłaniu na serwer wszystko działa jak trzeba. Natomiast gdy odpalam to na domowym komputerze (zainstalowany VertrigoServ) źle miesza. W kółko wyskakuje około 5 dokładnie takich samych zdań. Najlepsze jest to, że zawsze pojawiają się w tej samej kolejności! Jakim cudem tak się dzieje? co_jest.gif Czy może powstawać jakiś bład wynikły z konfiguracji VertrigoServ? W zasadzie to nic w ustawieniach nie zmieniałem.

Ten post edytował robert-s 26.06.2012, 21:47:14
Go to the top of the page
+Quote Post
zielu001
post 26.06.2012, 22:44:36
Post #2





Grupa: Zarejestrowani
Postów: 87
Pomógł: 3
Dołączył: 15.08.2009

Ostrzeżenie: (0%)
-----


Ja bym pierwsze sprawdził wersje PHP ;p Najlepiej zainstalować najnowsze. Możliwe że w tej wersji która jest w VertrigoServ jest za stara i któraś z funkcji ma trochę inne działanie..


--------------------
"Zło do triumfu potrzebuje tylko tego, aby dobrzy ludzie nic nie robili"
Go to the top of the page
+Quote Post
robert-s
post 26.06.2012, 22:57:18
Post #3





Grupa: Zarejestrowani
Postów: 17
Pomógł: 1
Dołączył: 24.05.2012

Ostrzeżenie: (0%)
-----


Najnowsza była. Zresztą teraz zmieniłem na WAMPSERVER i to samo. Musi być jakieś racjonalne wyjaśnienie... Na hostingu losuje jak trzeba. U mnie na localhost zachowuje się jakby zapamiętał kilka wyników i wyświetlał kolejno co_jest.gif Intrygujące... I dzieje się tak tylko przy dużej ilości tekstu.

Ten post edytował robert-s 26.06.2012, 22:57:58
Go to the top of the page
+Quote Post
IProSoft
post 26.06.2012, 22:59:12
Post #4





Grupa: Zarejestrowani
Postów: 479
Pomógł: 97
Dołączył: 6.09.2011
Skąd: php.net :)

Ostrzeżenie: (0%)
-----


Nie zagłębiałem się w kod ale to, że pojawiają się w tej samej kolejności prawdopodobnie wynika z wersji PHP bo chyba od 5+ array_rand nie miesza zwracanej tablicy, dodaj po:
  1. $elements = explode($this->delimiter, $text);

  1. shuffle($elements);

i sprawdź czy zmieni się cokolwiek.


--------------------
Manual prawdę Ci powie.
Go to the top of the page
+Quote Post
robert-s
post 26.06.2012, 23:30:46
Post #5





Grupa: Zarejestrowani
Postów: 17
Pomógł: 1
Dołączył: 24.05.2012

Ostrzeżenie: (0%)
-----


Częściowo pomogło tzn. z tych 100 zdań losują się już wszystkie. Jednak dla danego zdania zawsze losowane są te same synonimy. I nie ma reguły, że jest brany zawsze np. pierwszy wyraz z {wyraz 1|wyraz|2wyraz 3}, ale przy drugim, trzecim itd wylosowaniu danego zdania zawsze wygląda ono tak samo. Znowu problem z zagnieżdżeniami występuje tylko przy dużej ilości tekstu. Przy 5 zdaniach jest ok. Sprawdzane tylko lokalnie, na serwerze już nie mogę bo domownicy się burzą, że nie mogą spać smile.gif Trzeba będzie stawić czoło problemowi dopiero rano.

Ten post edytował robert-s 26.06.2012, 23:32:43
Go to the top of the page
+Quote Post
Niktoś
post 27.06.2012, 00:08:04
Post #6





Grupa: Zarejestrowani
Postów: 1 195
Pomógł: 109
Dołączył: 3.11.2011

Ostrzeżenie: (10%)
X----


Spróbuj w funckcji mixText za liniką:
$elements = explode($this->delimiter, $text);

dodać SLEEP(10);
mianowicie:
  1. $elements = explode($this->delimiter, $text);
  2. sleep(10);
  3. return $elements[array_rand($elements)];

Poza tym masz literówke:
str_ireplace-co to za polecenie?

Ten post edytował Niktoś 27.06.2012, 00:24:37
Go to the top of the page
+Quote Post
phpion
post 27.06.2012, 07:07:28
Post #7





Grupa: Moderatorzy
Postów: 6 072
Pomógł: 861
Dołączył: 10.12.2003
Skąd: Dąbrowa Górnicza




@Niktoś:
str_ireplace

@robert-s:
Spróbuj użyć tego (konieczne PHP 5.3):
  1. class text {
  2. public static function shuffle($text) {
  3. $text = (string)$text;
  4.  
  5. while(strstr($text, '{')) {
  6. $text = preg_replace_callback('/{([^\{\}]*?)}/', function($text) {
  7. $text = explode('|', $text[1]);
  8.  
  9. return $text[array_rand($text)];
  10. }, $text, TRUE);
  11. }
  12.  
  13. return $text;
  14. }
  15. }
  16.  
  17. echo text::shuffle('siema {pion|phpion|{Michał|Michałku}} {jak sie masz|co u ciebie}?');
Go to the top of the page
+Quote Post
robert-s
post 27.06.2012, 09:43:53
Post #8





Grupa: Zarejestrowani
Postów: 17
Pomógł: 1
Dołączył: 24.05.2012

Ostrzeżenie: (0%)
-----


SLEEP odpada, bo skrypt wykonuje się niemiłosiernie długo przy długich zdaniach. Zawsze Timeout, więc nawet nie mogę porównać.

W nawiązaniu do wersji bez żadnych modyfikacji. Hosting z wersją PHP 5.3.1326. Działa dobrze. Hosting z wersją PHP 5.2.17 również. WAMPSERVER PHP 5.3.13 w kółko w wyniku daje dokładnie 9 tych samych zdań.

Dodanie shuffle($elements); u mnie na localhost poprawia nieco losowość, ale i tak jest bardzo słaba. Dochodzi trochę zdań, ale na pewno nie losują się z całej puli. Z synonimów zagnieżdżonych prawie zawsze losuje się to samo. To jest przykładowy plik zawierających dwieście wygenerowanych linijek i posortowanych według długości. Proszę się nie przestraszyć, bo to jest bełkot, niemniej pokazuje problem:

https://dl.dropbox.com/u/46580461/zlemieszanie.txt

Dla porównania plik wygenerowany tym samym kodem, na hostingu z PHP 5.3.1326

https://dl.dropbox.com/u/46580461/dobremieszanie.txt

I na szybko zrobiony pliczek, który generuje te 200 linijek razem z tekstem źródłowym:

https://dl.dropbox.com/u/46580461/mieszacz.php

W zasadzie powinienem się cieszyć, że kod dobrze działa w miejscu docelowym, ale... Sytuacja jest dla mnie niezrozumiała puke.gif i ciężko mi się jest z tym pogodzić, ponieważ jestem człowiekiem dociekliwym. Zauważyłem jeszcze, ze u mnie kod wykonuje się o wiele dłużej niż po wgraniu na hosting. Teraz pobawię się kodem dostarczonym przez phpion'a. Zagadka tak czy inaczej zostaje.
Go to the top of the page
+Quote Post
Niktoś
post 27.06.2012, 10:03:39
Post #9





Grupa: Zarejestrowani
Postów: 1 195
Pomógł: 109
Dołączył: 3.11.2011

Ostrzeżenie: (10%)
X----


Może zrób sobie experyment. Na localchoście póść np 30-40 razy w pętli losowanie dużej liczby i wyświetl to.Zrób to samo dla rand(),srand() i mt_rand(). Zobaczysz efekty i różnice.
Coś takiego:
  1. for($i=0;$i<10;$i++){
  2. $dane=rand(0,1000000000);
  3. echo $dane;
  4. }


Potem przed $dane spróbuj dodać polecenie sleep().

Ten post edytował Niktoś 27.06.2012, 10:09:36
Go to the top of the page
+Quote Post
robert-s
post 27.06.2012, 13:23:01
Post #10





Grupa: Zarejestrowani
Postów: 17
Pomógł: 1
Dołączył: 24.05.2012

Ostrzeżenie: (0%)
-----


Nie widzę jakiś różnic. We wszystkich przypadkach liczby są dobrze losowane, bez takich powtórzeń. Przy sleep też.

Kod phpion'a daje taki sam efekt jak w załączonych wyżej plikach. Pewnie wina leży w konfiguracji i złym działaniu array_rand, tylko gdzie dokładnie? Znamienne jest to, że błąd objawia się przy dużym obciążeniu (długi tekst z synonimami zagnieżdżonymi). Można w jakiś elegancki i wydajny sposób zastąpić array_rand?

Edit: Problem rozwiązany przez napisanie zupełnie innego kodu bez array_rand. Niemniej jakby ktoś znał prawdopodobną przyczynę takiego stanu rzeczy, niech da znać.

Ten post edytował robert-s 27.06.2012, 13:23:25
Go to the top of the page
+Quote Post

Reply to this topicStart new topic
1 Użytkowników czyta ten temat (1 Gości i 0 Anonimowych użytkowników)
0 Zarejestrowanych:

 



RSS Wersja Lo-Fi Aktualny czas: 13.06.2025 - 13:34