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

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.

Ispravak, HTML je korišten kasnije problematičnog djela codea. (Ali ocke, moguće valjda da se to u RAMu definira negdje ranije)
I moram priznati da te ne razumijem najbolje tvoja objašnjenja kako to funkcionira na mašinskoj razini…ali i bez toga razumjevanja, ostaje mi upitnik iznad glave zašto je ovo dvoje različito:

generirajSkripte('page');

vs

$Page='page';
generirajSkripte($Page);

Meni ova dva gornja inputa izgledaju sasvim validna oba…pošto mi ovaj drugi input rezultira bugom, a ovaj prvi NE, onda sasvim opravdano ne smatram grešku svojom!

A što se tiče ovoga drugog djela tvog posta

, kako se taj echo i zašto izvršava unutar uvjeta koji je FALSE? :smiley:

btw, zanimljivo je da sam probao i ovu varijantu:

if(uvjet) //uvjet je znači FALSE, ako netko još nije ubrao…ali nekim čudom propušta.
{
die(‘crkni pobogu’);
if (!mkdir($pathName, 0777, true)) {dies(‘failed…’);} //VRAG
}

…u ovoj varijanti sam dobio da mkdir ne radi svojeglavo unutar FALSE uvjeta, ali opet niti ova die funkcija nije abortirala program.

I još nešto. Znači postigao sam da u nekim xx okolnostima program proradi. Radio je 5,6 puta …i onda bez ikakvog razloga, bez ikakve promjene codea se vratio u bugovito ponašanje.

Ocke, to bi mogao prihvatiti da mu se nekakav RAM izšeremetio u tih 5,6 puta …pa da je opet dobio popizditis.No nigdje ne vidim što sam mu ja to neregularno dao, da mu priuštim taj popizditis?

Evo onda, malo više od codea, pa tko nađe…svaka mu dala!!!

…code uskoro…

Znači prvi step, uzimam iz URL-a, potrebne elemente patha:

function getURL() 
	{
	$PageURL = 'http';
	if (isset($_SERVER["HTTP"]) && $_SERVER["HTTPS"] == "on") {$PageURL .= "s";}
	$PageURL .= "://";
	if ($_SERVER["SERVER_PORT"] != "80") 
		{
		$PageURL .= $_SERVER["SERVER_NAME"].":".$_SERVER["SERVER_PORT"].$_SERVER["REQUEST_URI"];
		} 
	else {$PageURL .= $_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"];}
	return $PageURL;
	}

function getUrlParams($url,$rootDomain)
	{
	$rootDomain=rtrim($rootDomain,'/');

	$index=strpos($url,$rootDomain);
	if($index===false)die('Moras podesiti parametar "rootDomain" u index.php!');
	
	$url=trim(substr($url,$index+strlen($rootDomain)),'/');
	$parts=explode("/",$url);

	return $parts;
	}

$UrlParts=getUrlParams(getURL(),$Config['rootDomain']);

$PageNames=array();
$ScriptNames=array();
for($x=0;x<count($UrlParts);$x++)
	{
	$PageNames[$x]=($val=="") ? 'main': $val;
	$ScriptNames[$x]= urlToScriptName($PageNames[$x]);
	}

…ocke, sad imamo kako sam došao do varijabli $PageNamse i $ScriptNames.

Funkcija urlToScriptName(), ne radi ništa odveć pametnoga…samo skraćuje naziv prema zadanom iz Config filea.

function urlToScriptName($urlPart) 
	{
	global $Config;
	return isset($Config['script_name_max_length']) ? substr($urlPart,0,$Config['script_name_max_length']) : substr($urlPart,0,7);
	}

Sad ajmo vidjeti funkciju generirajSkripte(), možete jednostavno gledati moju debuging verziju te funkcije…gdje je SVE ogoljeno, tako da me NE PITAJTE više što se nalazi u tamo nekoj xx funkciji koju niti ne koristim za debuging!!

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

A pava izgleda ovako: (Zaista nebitno proučavat, kad ju nisam ni koristio kod debugiranja…i bug ne ovisi očito o ničemu što se extra pojavljuje ovdje)

function generirajSkripte($pageFolderName,$path,$scriptName,$f=array())
	{
	// echo 'hocem li generirati: '.$pageFolderName.', '.$path.', '.$scriptName;br();
	// echo 'to je path: '.$pageFolderName.$path;br();

	if(!file_exists ($pageFolderName)){if (!mkdir($pageFolderName, 0777, true)) {dies('Failed to create folders...');}}

	if(!file_exists(noSlashRight($pageFolderName.$path))) 
		{
		//echo 'ne postoji: '.$pageFolderName.'/'.$path;br();

		//ako ne postoji kreiran folder..prvo njega radi
		if (!mkdir(noSlashRight($pageFolderName.$path), 0777, true)) {die('Failed to create folders...');}
		
		//model.php
		$file=fopen($pageFolderName.$path.$scriptName."_m.php", "w");  
		fwrite($file, "<?php \n\n\n\n\n?>"); fclose($file);
		
		//wiev php (content)
		$file=fopen($pageFolderName.$path.$scriptName."_w.php", "w"); 
		$fileTxt=isset($f['text_w']) ? $f['text_w'] : ""; 
		fwrite($file, $fileTxt );
		fclose($file);
		
		//file.js
		$file=fopen($pageFolderName.$path.$scriptName.".js", "w");
		fwrite($file, "/*\n onload(function()\n\t{\n\t});\n*/"); 
		fclose($file);
		
		//file.css
		$file=fopen($pageFolderName.$path.$scriptName.".css", "w");
		fclose($file);

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

I sad, adje da vidimo kako sam radio poziv te funkcije (isto pojednostavljeno kako sam radio u debuging verziji)

path je s kojim sam radio za debugiranja: root.com/developingStyles/fonts

generirajSkripte('pages/',$PageNames[0],$ScriptNames[0]);  //ova je nebitna, ova ispod je uzrokovala BUG
generirajSkripte("pages/",$PageNames[0].'/'.$PageNames[1].'/',$ScriptNames[1]);

NE RADI!

dok ovo radi:

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

a jedna onako provjera:

$PageNames[0].’/’.$PageNames[1] == ‘developingStyles/fonts’ -> baca TRUE

Ako bi tamo gdje sam razbio URL na djelove, ako bi tamo ručno isto zadao:

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

!!! onda bi isto radilo dobro !!!

So, očito neki vrag stiže iz partova URLa koji ga razremeti !!!

Probao sam zato partove iz URLa pročisiti i sa gore navedenom copyString() funkcijom…i to isto nije pomoglo.

I sad zaključno, ja NIGDJE ne prosljeđujem funkciji generirajSkritpe nazive foldera koje je ona izgenerirala xd.
I to ih je izgenerirala unutar uvjeta koji ne smije biti ispunjen…jer se bug pojavljivao za vrijeme dok već postoji targetirani folder iz patha!!
I taj uvjet je besoumično čudno propuštao…tako da je dopustio da nastane taj čudnog imena folder…a nije dopuštao da se linija echo neposredno iznad izvrši.

Jeli išta jasnije? Nisam li ponovio sve što sam već i ranije stavio…već sam budala što se tog tiče da se toliko ponavljam.

Ti izgleda uopste nemas ukljucen error reporting. Druga stvar, funckija dies je li negdje deklarisana? Ako ti kreiranje foldera ne prodje onda ce uci u if statement i pokusati executati funkciju dies koja, u slucaju da nije deklarisana, je nepostojeca i doci ce do crashiranja.

Takodje, ono sto sam ti vec trazio, ako imas cudne returne na funkciji file_exists ispisi parametre koje proslijedjujes i kopiraj ovdje. Svi mi vidimo da ti nesto nakuvas i objasnjavas kako je sve isto ali hocu da vidimo copy/paste ispisa konacnog path-a koji prosljedjujes funkciji file_exists i mkdir, dakle uradi echo i kopiraj bez ikakvih opisivanja, kopiranja code-a nekih lijevih funkcija i sl.

Znači, našao sam i gdje se nalazi u mom dokumentu to ime koje dodjeli folderu koji nebi smio nastati…jer se linija mkdir nalazi unutar FALSE uvjeta xd.

Znači, na dnu skrpte imam include($Root.‘html/body.php’)

U tom body-u imam pak novi include…u tom includanom djelu imam pak novi include…i tako tamo negdje se includa jedna HTML skripta. Hoćete ju vidjeti cijelu, ili mi vjerujete kako izgleda HTML skripta?
Mislim skripta je ekstenzije .php, ali je čisti HTML code.

<div>
...
<img src='img/profile.png'>
...
</div>

i sad, kako sam huntao izvršavanje codea skroz do te html skripte sa die funkcijom. Skužio sam ako ne includam ovu skriptu (i još jednu drugu HTML koja se naknadno includa ) …da neće biti buga.

Onda sam izolirao te HTML skripte…i skužio ako u njima maknem img tag, da neće biti buga. Također sam skužio ako u njima promjenim src atribut, da ću promjeniti i naziv toga uljeza od foldera. (naravno, moram promjeniti src prije nego se uljez izgenerira)