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

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

Ma ok je to. Nego mora biti neka sitnica u pitanju.
Nesto poput trailing slash-a, byte ordering u ili slicno.
Ovako je samo nagadjanje. A da PHP ne sljaka, nisam bas siguran.

Probaj sa mb_strlen() funkcijom u copyString funkciji.

Moram priznati da ne kužim tvoju logiku? :confused:

Pogledaj dva posta iznad svog…razmisli malo o varijantama promjene inputa koje uzrokuju bug, ili ne uzrokuju bug?

Kakve to veze može onda imati sa ičim nakon toga? Sve što se dešava nakon toga je očito samo posljedica…a uzroke se treba tražiti prije spomenutog.

A prije je jedina razlika dali ručno zadajem vrijednosti varijablama. (Što u production smislu se naravno ne može koristiti ) …ili vrijednosti varijablama dodam tako da razbijem url i protrčim kroz njega.

Znači, nešto je zapelo u URLu, što buni kasnije PHP. A da ste shvatili na koji način buni PHP, stvarno nebi pitali što je u makePath() funkciji…time više što sam naveo da sam sve svoje funkcije izbacio, cijeli code sam ogolio u svrhu debugiranja. A naravano da sam u 10+ sati debugiranja i provjerio koje varijable ulaze i izlaze iz mojih funkcija. I mada je sve to točno bilo, i dalje sam ih izbacio da se creatifcode ne mora više kladiti da greška tamo leži…

Ali ako te baš zanima, funkcija izgleda ovako:

function slashRight($string)
	{
	return rtrim($string,'/').'/';
	}
function noSlashRight($string)
	{
	return rtrim($string,'/');
	}
function makePath($list)
	{
	$path='';
	foreach($list as $val)
		{
		$path.=slashRight($val);
		}
	//echo 'makedPath: '.noSlashRight($path);br();
	return noSlashRight($path);
	}

…jednostavno mi garantira da će sljedeće povezati u ispravan path, npr:

makePath(array('neki/','path','do/','necega','da/','ne','brinem','koji/','dio','zavrsava/','sa','sleshom','a','koji','ne'));

Probao, ista stvar.
Da stvar bude još bolja, još se nešto desilo!
…pošto sam već krenuo u drugom smjeru s alternativom, morao sam vraćati malo da isprobam tvoj code. (Mada ništa drugačijeg ovdje ne vidim nego što ja to već radim sa explode)

…uglavnom, vratim ja svoj code prvo na svoju staru varijantu, i ono radi!!!

Prvo se mislim, kako ću ja sad objasniti da zaista nisam ništa vitalnog dirao a da je proradilo…i da je PHP zaista pošeremećen. (Jer sam gotovo siguran da ništa vitalnog i nisam dirao …tek neke okolne stvari poslagivao)

Ono što me još više mučilo, sviđalo mi se da radi…a mrzio sam se što ću sad to tako ostaviti pa da pukne kad sljedeći put poželi. S druge strane, vjerovao sam da ga je pošeremetila nekakva nebitna okolna sintaksa…da se to sad izbilo samo od sebe…i da će se bug teško i vratiti.

I kliknem jednom…uredno napravi foldere. Obrišem foldere…kliknem opet…on opet uredno kreira foldere. Kliknem dok su kreirani, ne stvara te nove uljeze od foldera iz uvjetu koji nije ispunjen sa imenom iz sto milja udaljenog HTML img taga, hahah…preskakajući echo naredbu! (haha, moram to ponavljati xd, jer je faking noooo senseeeeee)

I klikam ja tako to jedno pet šest puta…i hop, problem se vratio…gromom iz vedra neba…ne dirajući code uopće!

Tu sam probao onda tvoju varijantu razbijanja URLa, no kao što rekoh…ista stvar…ja sam bome izgubio dva dana, i nastavljam s alternativnim načinom, ovoga mi je zaista dosta.

Sta su ti bogati “cudni folderi” i gdje se kreiraju? Druga stvar, sve te konkatenacije dodjeljuj varijabli i onda tu varijablu predaj funkciji a nama ispisi. Dakle, sve to sto radis u ovoj funkciji generirajSkripte ispisi, ovako niko pojma nema sta te neke tvoje funkcije vracaju i sta si uopste predao funkciji a to je prva stvar koju treba da provjeris prilikom debagiranja.

Dakle, ovo: makePath(array($pageFolderName,$path))) dodijeli nekoj varijabli i nju predaj funkciji a isto tako ispisi i stavi ovdje. I gdje god imas slicnu stvar u ovoj funkciji generirajSkripte uradi isto. Tako ce kod biti pregledniji a imacemo i informaciju sta predajes jer ovako samo mozemo nagadjati da je sve predato kako treba.

Jelda da nisi ni ti shvatio :D. Kako da ispišem kad ponavljam po stoti put da linija echo bude preskočena, zanemarena…kao da je nema…i točno u onom momentu kad imam bugovito ponašanje. A odmah nakon te linije echo, ona vražja linija stvara čudan folder. Zašto je čudan? Zato jer se zove svojeglavo…dok ja prosljeđujem u parametru funkcije jedno ime za naziv foldera, on se nazove sasvim drugačije.

Kakav bi to morao biti bug da mi uleti ime foldera koje nigdje niti ne spominjem? Eto tako došlo PHPu da izmisli ime? Upravo to, eto tako je došlo PHPu da izvrši tu liniju kreiranja foldera sa nekim čudnim imenom. Zato i jeste echo linija preskočena…jer se nešto opako u ovom slučaju pošeremetio.

I ime po kojem se nazove folder…to ime sam našao u miljama udaljenoj HTML skripti. …i to ime pripada src-u jednog img taga, hehe. Kako mijenjam ime src tagu, tako mijenjam ime čudnom folderu koji se neželjeno generira.

Evo još jednom, maksimalno sažeto i pojednostavljeno što se dešavalo. Nema s ovime veze nikakav makePath() ili bilo koja druga interna funkcija…jer sam sve sažeo na tri linije codea …a i dalje nije radilo…
Znači imamo situaciju:

if(uvjet)
{
echo u ovoj liniji NE RADI
makeFolder(‘pero’) //mi napravi folder Ivo
}

uvjet je provjera postoji li pero, tako da ga ne radi opet ako postoji …jer PHP bi tu sam po sebi vrisnuo error!
…a bug se pojavljuje za vrijeme dok postoji pero, znači dok se ništa nebi trebalo izvršavati unutar uvjeta!!!

ako zakomentiram makeFolder, neće biti stvoren Ivo (što daje sigurne naznake da bug dolazi odavde, a opet echo funkcija iznad ne radi…što će reći da uvjet zapravo i ne propušta)
Mislim, makeFolder() radi, dok echo iznad ne radi ništa??? Reklo bi se “helloooou”…ljudska greška? Pa postigni to sve da želiš, i neće ići!!!
ako uvjet proširim sa if(0 && uvjet) -neće opet biti Ive (što dodatno daje do znanja da je uvjet zaista propuštao i da se ivo stvarao unutar uvjeta)
ako uvjet proširim sa if(1 || uvjet)-> onda echo proradi, a makeFolder više ne stvara ivu nego baci error da pero već postoji.

I da stvar bude bolja, to se sve nalazi unutar neke funkcije generiraj($pageName)

ako ja tu funkciju pozovem sa generiraj(‘pero’) -> onda radi sve po očekivanju
ako pak napravim:
$page=‘pero’; //tj. ako ovo napravim dodjeljivajući peru iz urla!!!
generiraj($page) -> onda se stvori Ivo

Nadam se da sam sad bio jasniji koliko je ovo sve zajedno bilo nemoguće…dobro razmislite o gore navedenim kombinacijama, pa ćete vidjeti koliko ništa nema smisla i da je gotovo nemoguća ljudska greška za izazivanje ovakvog stanja sve da i želimo.
…još ako ste shvatili od kuda je čupao Ivu… xd

Ne cupa iz nekog udaljenog html-a vec iz sadrzaja memorijske lokacije koju pogresno referenciras time sto ti negde nije dobro definisana promenjiva. To je prilicno uobicajena greska programera.

Jako bi pomoglo kada bi umesto konfuzne price prosledio kompletan kod i seriju podataka koje koristis. Tako bi i mi mogli reprodukovati gresku i pomoci ti da nadjes gde si pogresio.

1 Like

Hm, mozes li pojasniti ovo s memorijskom lokacijom. Ne pricas nadam se o cache memoriji?

A što se tice svega zajedno, mogu i ja postaviti protupitanje svima koji misle da je ovo uobicajeno ponasanje PHPa. Ajde vi onda postignite na svjestan nacin da unutar uvjeta imate dvije linije codea…i da prva linija echo ne radi…a da druga linija radi, koja moze biti sto vas je god volja. Cak smijete imati i uvjet po vasoj volji da bude true ili false.

Pa samo ako taj segment ove price shvatite da je neizvediv, mozda utvrdimo da se sve ovo nikako nebi smjelo desavati…

A ja u ovom bugu, mogu izvuci jos par ovakvih nebuloza.

Pričam o tome kako programski jezici funkcionišu na mašinskom nivou i ovde se radi RAM memorijskoj lokaciji na kojoj bi trebala biti promenjiva koju si loše deklarisao, ali ona nije tamo već neki slučajan sadržaj (u ovom slučaju html korišćen ranije za generisanje nečeg drugog, odnosno sadržaj neke druge promenjive koja je bila deklarisana ranije i za koju je korišten upravo taje memorijski prostor). Za razliku od drugih jezika PHP je prilično slobodan što se tiče deklarisanja promenjivih i to omogućuje programerima da prave greške ovog tipa.

Drugo, echo se verovatno izvršava, ali prilikom izvršavanja sledećeg reda dolazi do greške (zbog loše deklarisane promenjive), te se izvršava deo u tvojoj funkciji koji generiše folder, tvoja funkcija se ne izvršava do kraja kako treba i kako se proces ne završava uspešno generisani output ostaje u memoriji i ne šalje se na ekran. Sasvim regularno ponašanje. Ako želiš da ti neko pomogne pošalji sve detalje koji omogućuju reprodukciju greške, uključujući i ulazne podatke. Mislim da bez toga nema smisla dalje razgovarati.

1 Like

I ja uporno tvrdim da nam trebaju kompletan kod i podatci, kako bi mogli reproducirati greske ali autor teme to uporno odbija i tupi i dalje po svom.

To da ti jednu liniju unutar istog if statement-a ispise a drugu ne prosto ne moze biti tacno. Greska nije do PHP vec do tebe. Ono sto sam ti pisao se ne odnosi na ispis unutar if statement-a vec prije njega dodijeli makePath varijabli i ispisi a nakon toga izvrsavaj dalji kod.

Znaci ispisi parametar prije nego sto ga dodijelis funkciji a ne nakon sto statement fejla.

Uradi ovo:

global $Config;
$filename = makePath(array($pageFolderName,$path));
echo $filename;
	if(!file_exists($filename)) 

Da vidimo sta si proslijedio funkiji file_exists. Problem je do tebe/tvog code-a u to budi siguran.

Pa poslao sam sve što je relevantno…i više od toga. Što bi ti da ti pošaljem sve fileove iz projekta koji ima stotinjak skripti…i preko milijun karaktera codea?

Zar nije dosta što sam izolirao problem, ogolio ga od svih svojih funkcija (tvoja oklada je tu već pala da je greška u nekim od tih funkcija) …i nakon što sam ga ogolio, nelogičnosti ponašanja su trivijalno očite.
Detektirao sam i uzrok tih nelogičnosti…i okolinu koja mora biti prisutna da bi se te nelogičnosti aktivirale. (Jer uzrok nije sam po sebi dovoljan, a niti okolina)

I onda se nađu pametnjakovići da mi kažu da napravim echo funkciju i pogledam koje parametre imam tamo?? To se na tebe @remark odnosi. Pa bemu, ne pratiš. Nema više funkcije makePath(), to sam sve UKLONIO! I da, moguće je očito da se echo linija preskoči, a ova iza nje izvrši. …a to što kažeš “da to na prosto ne moze biti tacno”, e to ti i ja kažem. I zato je jasno da greška dolazi od zbunjenog PHP-a.

Inače, echo mi radi prije if uvjeta, i nijednom se nije pojavio nikakav parametar unutar funkcije koji nisam očekivao da bude tamo. Valjda nisam glup da u dan i pol debugiranja to nisam provjerio…i sad već postaje naporno koliko puta sam iste stvari objasnio, da bi ih opet ponavljao.