A što kad nađem bug u PHPu :s

Vidio sam hrpu čudnih bugova, ali za ovog ruku u vatru dajem da nije do mene…nego do parsera php-a…ili čega već.
Sitaucija je znači sljedeća…sažet ću strukturu uvjeta codea da dočaram:

imam funkciju koja mi generira foldere i određene skripte unutar foldera prema pathovima koje imam. U načelu to treba raditi samo lokalno kad prvi put linkam prema nekom pathu, da mi genenrira folder i skripte ukoliko još nisu generirane.

function generirajSkripte($pageFolderName,$path,$scriptName)
	{
	global $Config;

	if(!file_exists(makePath(array($pageFolderName,$path)))) 
		{
		echo 'ne postoji path: '.makePath(array($pageFolderName,$path));
		//die('miki');
		//ako ne postoji kreiran folder..prvo njega radi..i to je vrazja linija koja zahebava!!!
		if (!mkdir(makePath(array($pageFolderName,$path)), 0777, true)) {dies('Failed to create folders...');} //VRAG

		//...ovdje generiram skripte u tom folderu, no to dodje nebitno...

		echo 'Generirane su auto skripte za path: '.makePath(array($pageFolderName,$path));br();
		}
	}

…u načelu, sve radi prema očekivanju…samo i više od toga. Znači ova linija VRAG radi neke čudne stvari i kad gornji uvjet nije ispunjen!!! WTF?? :S

Kako znam da točno ta linija, i kako sam siguran da gornji uvjet nije ispunjen!!?

Pa znam da je ta linija, jer se taj extra job ne desi ako nju zakomentiram.
A kako znam da gornji uvjet nije ispunjen…pa osim što sam siguran da file iz uvjeta postoji, pored toga echo funkcija bude preskočena…samo se desi VRAG linija.
A za slučaj da odkomentiram liniju die(‘miki’) …onda se ne desi nikakav die(). Ludo…ludo…

A da stvar bude luđa, taj extra job je totalno no-sense, ne povezan sa ikakvim inputima koje zadajem…tj. s pathovima koje zadajem da budu stvoreni. Nego mi u tom folderu gdje radim te neke skripte izgenerira čuda i čuda…tj. nekim čudom sve grafika koja se nalazi u jako udaljenom img folderu, se izgenerira u tom folderu gdje radim par skripti. I to se ne izgenerira kao .png fileovi, nego kao pripadajući folderi koji nose nazive slikica, tj. png fileova. Znači, ništa nema smisla :confused: …a opet se vidi da radi sa nekom svojom ludom logikom. Jer uzima te neke fileove…pa iz neke slikice izgenerira nastavke imena, onako kako ih ja dodajem željenim skriptama.
Strašno :open_mouth:

Ono što je još bitno spomenuti, funkciju generirajSkripte(), u ovom slučaju kad je bug, pozivam dva puta uzastopno iz jedne foreach petlje.

Znači url mi se sastoji od parthova webStyles i fonts “webStyles/fonts”

for petlja prvo gleda part1 (webStyles) i radi njegovu strukturu, zatim gleda part2 (fonts) i radi njegovu strukturu.
E sad, ako pozovem funkciju samo za part1, neće biti buga. Isto tako ako pozovem funkciju samo za part2, također neće biti buga. (niti u jednom niti u drugom slučaju se ništa ne dešava…jer kao što rekoh, uvjet je 99.999% NE-ispunjen, i code se tamo ne smije izvršavati!)

No kad pustim for petlju i odradim oba poziva jedan za drugim, onda php nekako zaluta u taj dio codea (i to tako na preskokce da preskoči echo funkciju xd) :S. Probao sam staviti sleep(1) za svaki korak for petlje nebi li se dobila funkcija mkdir() ako ima kakvih vlastiti kašnjenja…no nije pomoglo :/.

Ako izuzmem da je jako čudno da se unutar funkcije preskače echo linija, pa nešto izvršava…i to još na jako iskrivljen način…mogu reći da sam suzio izvor problema na jedno drugo mjesto. (I dalje meni apstraktno)

Znači, fokusirao sam se na mjesto poziva funkcije iz for petlje…i to sam prebacio na ručno:

generirajSkripte('pages/','developingStyles/','develop');
generirajSkripte('pages/','developingStyles/fonts/','fonts');  

…i tu sve dobro radi!!!

Zatim, umjesto da vrtim for petlju, izvukao sam ručno parametre iz njihovih varijabli:

generirajSkripte($Config['page_folder_path_name'],$Pages[0].'/',$ScriptNames[0]);
generirajSkripte($Config['page_folder_path_name'],$Pages[0].'/'.$Pages[1].'/',$ScriptNames[1]);  

…i to NE radi!!!

No ironični dio je da ove varijable moraju davati (i daju) upravo ono što sam gore ručno unio, to mogu provjeriti i sa ispisom:

echo 'IRONIJE li: ';br();
echo $Config['page_folder_path_name'].', '.$Pages[0].'/, '.$ScriptNames[0];br();
echo $Config['page_folder_path_name'].', '.$Pages[0].'/'.$Pages[1].'/, '.$ScriptNames[1];br();  

koji daje kao što je očekivano:

IRONIJE li:
pages/, developingStyles/, develop
pages/, developingStyles/fonts/, fonts

hmmmmmmmmm

Ja se dam kladit da si ti negdje nesto sjebao u nekoj od svojih funkcija ili toj generirajSkripte ili toj makePath.

ma i ja sam se na to kladio prvo…ali sve sam ogolio, baš sve.
Pogledaj ovu temu: PHP problem kod zbrajanja stringova preko varijabli , i vidjet ćeš kako mali promjena ulaznog parametra drastično mijenja sve naknadno.

Što je najbolje, niti nije promjena ulaznog parametra…nego php reagira na to dali mu zadam parametar sa varijablom ili ručno unesem string :s. Tu je sigurno neka caka oko vrste navodnika i backslesha…no bez obzira na to, ludo je da imamo situaciju:

if(uvjet)
{
this line of code dont work (full basic code, echo function)
this line work, but extremly different from suposed!!
}  

…i to sve za vrijeme dok uvjet NIJE ispunjen!!

Ne escapeas dobro tvoje stringove ili ih uopce u funkciji ne escapeas

ponovo kazem, kladim se da si nesto zajebao u nekoj od tvojih funkcija.

Evo, pojednostavnio sam funkciju do kraja, a isto se dešava:

function generirajSkripte($pageFolderName,$path,$scriptName)
	{
	if(!file_exists(rtrim($pageFolderName.$path,'/')))
		{
		if(!mkdir(rtrim($pageFolderName.$path,'/'),0777,true)){die('failed to create...');};
		echo 'generirane su auto skripte za path: '.$pageFolderName.$path;
		}
	}

…znaci nema više mojih dodatnih funkcija, sve je clean code.

Razmišljao sam o tome. Reci kako ih najpravilnije escapeat?
No ono što me muči…sve da su i nepravilno eseapani, kako može biti da se linija codea preskoči…pa onda linija codea iza napravi svašta neočekivanoga??

Pazi molim te varijante:

Svi pozivi se odnosi kad zapravo postoji: $pageFolderName.$path

function generirajSkripte($pageFolderName,$path,$scriptName)
	{
	if(!file_exists(rtrim($pageFolderName.$path,'/')))
		{
		echo 'test echooooooooooooo';
		if(!mkdir(rtrim($pageFolderName.$path,'/'),0777,true)){die('failed to create...');}; //čudna linija
		echo 'generirane su auto skripte za path: '.$pageFolderName.$path;
		}
	}

//result: dobijem čudne foldere, ali NE ispiše se ‘test echo’
.
.
.

function generirajSkripte($pageFolderName,$path,$scriptName)
	{
	if(!file_exists(rtrim($pageFolderName.$path,'/')))
		{
		echo 'test echooooooooooooo';
		// if(!mkdir(rtrim($pageFolderName.$path,'/'),0777,true)){die('failed to create...');}; //čudna linija
		echo 'generirane su auto skripte za path: '.$pageFolderName.$path;
		}
	}

//result: NE dobijem čudne foldere, jer sam zakomentirao čudnu liniju
.
.
.

function generirajSkripte($pageFolderName,$path,$scriptName)
	{
	if(0 && !file_exists(rtrim($pageFolderName.$path,'/')))
		{
		echo 'test echooooooooooooo';
		if(!mkdir(rtrim($pageFolderName.$path,'/'),0777,true)){die('failed to create...');}; //čudna linija
		echo 'generirane su auto skripte za path: '.$pageFolderName.$path;
		}
	}

//result: NE dobijem čudne foldere, jer sam zacementirao ukidanje uvjeta sa nulom!
.
.
.

function generirajSkripte($pageFolderName,$path,$scriptName)
	{
	if(1 || !file_exists(rtrim($pageFolderName.$path,'/')))
		{
		echo 'test echooooooooooooo';
		if(!mkdir(rtrim($pageFolderName.$path,'/'),0777,true)){die('failed to create...');}; //čudna linija
		echo 'generirane su auto skripte za path: '.$pageFolderName.$path;
		}
	}

//result: forsiram uvjet sa jedinicom, čudnovata linija mi baci grešku da je pozvana kad folder već postoji i aktivira se test echo:

test echooooooooooooo
Warning: mkdir(): File exists in C:\xampp\htdocs\CROSS_PROJECT_SCRIPT\controllers\initialModel_crossProject.php on line 62
failed to create…

Ako razmisliš o svim gornjim varijantama, uvidjet ćeš da ovaj mkdir iz čudnovate linije postoji negdje izvan ovog blocka koda, gdje ga je PHP parser ugnjezdio. …te se on trigira neovisno o uvjetu file_exist() koji propušta ovaj block koda da radi, i isto tako se tamo negdje trigira sa nekakvim svojim parametrima. Ako ga ovdje zakomentiram, zakomentirao sam ga i tamo negdje.
Ako forsiram blokiranje uvjeta sa nulom, također sam ga ugasio i tamo negdje. No ako forsiram propuštanje uvjeta sa jedinicom, onda sam ga od tamo negdje dovukao ovdje…i to onda sa pravim parametrom…i onda baci pravu grešku da file već postoji te da ga ne može opet napraviti.
To je moje jedino objašnjenje za ovu čudnu situaciju…

Koristis li dobar path za mkdir(); sta radi makePath() funkcija?

A što bi ti značio dobar path s obzirom na ovo ponašanje?
Pogledaj ovu temu: PHP problem kod zbrajanja stringova preko varijabli …vidi da nema path previše veze!

Što se tiče makePath(), zbog debugiranja sam izabcio to da ne buni…sve sam ogolio! Ali to je inače funkcija koja poveže određene stringove u ispravan path, bez obzira jeli neki part stringa (patha) došao sa backslashom ili nije…

Mislio sam da li se koristi absolute path, pa mozda nesto u vezi sa tim.
Pretpostavljam da se testira relative path.
Prelist’o sam onu temu vec. Idem da je pogledam opet.

Heh da…ponašanje kad program preskače očitu liniju koda ne može baš biti povezano sa krivim pathom na taj način :slight_smile: …i to kad ju još preskače unutar uvjeta koji ne može biti ispunjen. I to sve se još zbuni zbog “neznatne” promjene načina prosljeđivanja parametara funkciji…ma strahota.

Uglavnom, našao sam gdje je bug. I to, vjerujem da je PHPov bug, ne moj. Ili ću uskoro saznati da krivo koristim neke stvari :smile:

Konačno mi je palo na pamet. (Ne znam kako se toga ranije nisam sjetio) …da neposredno nakon funkcije generirajSkripte() prekinem code sa die() funkcijom. Na taj način sam eliminirao dvojbu dali se zaista LUDI folderi stvore unutar te funkcije…ili se možda stvore negdje kasnije.
Iako zbog onog čačkanja sa komentiranjem ključne linije mkdir(), bilo je više nego očigledno da je ona uzrok stvaranju foldera…ali ovdje više ništa nije sigurno, pa sam krenuo u potragu jel se naknadno stvore folderi.

I vidi vraga, nakon što pozovem die() nakon generirajSkripte(), LUDI folderi nisu bili stvoreni. Tako sam pomicao funkciju die() prema dolje…pa u sljedeću includanu skriptu…pa sljedeću…i tragao za onom točkom gdje će opet LUDI folderi biti stvoreni.
To me dovelo do skripti koje imaju nekakav ovakav sadržaj- (malo budem skratio, nepotreban je sav html) :

echo "
<div id='userBox' class='valign_inline'>
	<div id='avatar_and_name_box' class='valign_inline'>
		<div id='avatarBox' class='krug24 p'><img src='img/profile-photo.png'/></div>
	</div>
</div>";

…i sad, unutar HTML-a se zagledamo u tag . Ako promjenim naziv toga taga, nema buga. (čak se i rimuje xd)
A ako promjenim prvi dio naziva src-a, do backslasha, isto riječ “img”, onda mijenjam i naziv LUDOG foldera koji će se neželjeno generirati.

E sad, jel ja tu nešto dobro nisam postavio…ili je ovo totalno neočekivano ponašanje PHP-a, to ćete mi vi odgonetnuti.

I da, ovo nije jedino mjesto gdje se uzrokoje bug, znači u još nekim skriptama koristim <img> tag, i situacija je identična! S time da bi napomenuo da neke skripte koje inkludam su čisti HTML bez php tagova, a spremljene su kao script.php.
Mislim, to je normalno valjda tako koristiti ako se ne varam?

Idem odspavati tjedan dana za ovu cjelodnevnu potragu xd…da sam barem ranije predahnuo, ranije bi se i sjetio ovog istjerivanja sa die() funkcijom…jooojjj…nakon pauze mi to odmah palo na pamet…

P.S. kod ove echo funkcije, rotiranje navodnika ne pomaže…isto tako ne pomaže svođenje cijelog echo ispisa u jednu liniju…

hahahaah…

dobro sam se nasmijao svemu ovome… drago mi je da si pronasao na kraju bug… to i jeste najbolje tako se najbolje uci… samo ubuduce lakse malo i sa postovima i generalno u zivotu polako :)…

stani na loptu, smiri igru, razmisli… u suprotnom vrisnut ces kroz par godina ne gine ti orah i uze oko vrata :smiley:

1 Like

Prijateljstva mene i bugova traju već 9 godina …ak nisam vrisnuo do sad, valjda nitni neću :stuck_out_tongue:

A ovo me zapravo nije toliko niti frustriralo…samo se sve toliko nenormalno ponašalo da nisam mogao naći prikladnijih riječi :D.

I konačno da sam prvi put doživio da greška nije do mene nego do “nečega” drugog. Valjda sam svih ovih godina hrpu puta pomislio “ovo mora da je nešto drugo krivo, jer ne vidim gdje bi bilo moguće da ja griješim” …pa sam opet ja ispadao uvijek kriv. No ovog puta zaista ne pronalazim svoju krivicu :slight_smile:

Opet ti kazem da je negdje greska do tvoga koda, a da bih ti ukazao gdje je greska treba mi puno vise da pogledam i prodjem kroz kod od ovoga sto si ti na forumu postao i sto ja imama vremena.

Moguće i dalje da si u pravu ;).
Reci mi kako da razbijem url na djelove po slashu, i da dodjelim te partove (stringove) nekim varijablama…a da to budu clean stringovi. Korijen problema mi uglavnom dolazi od tamo…i to nisam uspio istjerati na kraj.

Čak nakon razbijanja urla, probao sam djelove pročistiti na sljedeći način:

function copyString($string)  
    {  
    $send='';  
    for($x=0;$x<strlen($string);$x++)  
        {  
        $y=substr($string,$x,1);  
        switch($y)  
            {  
            case 'a':{$send.='a';break;}  
            case 'b':{$send.='b';break;}  
            case 'c':{$send.='c';break;}  
            case 'd':{$send.='d';break;}  
            case 'e':{$send.='e';break;}  
            case 'f':{$send.='f';break;}  
            case 'g':{$send.='g';break;}  
            case 'h':{$send.='h';break;}  
            case 'i':{$send.='i';break;}  
            case 'j':{$send.='j';break;}  
            case 'k':{$send.='k';break;}  
            case 'l':{$send.='l';break;}  
            case 'm':{$send.='m';break;}  
            case 'n':{$send.='n';break;}  
            case 'o':{$send.='o';break;}  
            case 'p':{$send.='p';break;}  
            case 'r':{$send.='r';break;}  
            case 's':{$send.='s';break;}  
            case 't':{$send.='t';break;}  
            case 'u':{$send.='u';break;}  
            case 'v':{$send.='v';break;}  
            case 'z':{$send.='z';break;}  
            case 'x':{$send.='x';break;}  
            case 'y':{$send.='y';break;}  
            case 'w':{$send.='w';break;}  
            case 'q':{$send.='q';break;}  
            case 'S':{$send.='S';break;}  
            default:$send.='#';  
             //nemam popis svih slova, jer za debug mi nisu bila sva potrebna
            }  
        }  
    return $send;  
    }  

koristeći gornju funkciju, probao sam:

$Pages[0]=copyString($url[0]); 
$Pages[1]=copyString($url[1]);  

…i neće raditi!!

dok sljedeća varijanta radi:

$Pages[0]='developingStyles'; 
$Pages[1]='fonts';  

…pa mi pliz odgonetni u čem može biti razlika, pošto sljedeće sto posto vrijedi!

$url[0]=='developingStyles'  -> TRUE 
$url[1]=='fonts'  -> TRUE

Ako nemaš odgovor na dato, i tvrdiš da je normalno da zbog takve razlike u inputu…mkdir() stvara folder sa imenom kojeg čupa iz img taga iz sto milja udaljenog HTML-a, i to mkdir() linija iz uvjeta koji se niti ne izvršava…
Zar zaista hoćeš reći da tvrdiš da je to normalno?? :open_mouth:

Pogledaj ovu temu PHP problem kod zbrajanja stringova preko varijabli …vidi u sažetom opisu koja nijansa u inputu uzrokuje bug, a koja ne uzrokuje bug.

Ja ti lijepo sad još kažem da ta razlika dolazi jedino zbog toga što su $Pages varijable definirane iz razbijenog urla.
Ako se ručno definiraju ista imena ka istim varijablama…onda stvar šljaka!

Očito nešto dolazi iz tog urla…zakeljeno nekako u stringu, no nevjerovatno mi je da funkcija copyString to ne uspjeva pročistiti…

Moze li kod od makePath() funkcije?
Ili barem provjeri da li izbaci dobre elemente niza.

Disclaimer: ne nipodastavam samo napominjem sta bih prvo gledao.

$query = $_SERVER['REQUEST_URI'];
    
    $queryParams = explode("/", $query);
    array_shift($queryParams);
    
    $params = array();
    foreach($queryParams as $qp)
    {
        $params[] = $qp;
    }
    print_r($params);

Evo nesto kako da raznijes request_uri