PHP xmlWriter resultaten naar log schrijven

Een bestaande applicatie die een XML export doet met XMLWriter moest voorzien worden van een mogelijkheid om de exacte XML output weg te schrijven in een log. Het script maakte in eerste instantie gebruik van directe output naar de browser:

$xml->openURI('php://output');

Om het totale resultaat van de XML output in een logfile te schrijven was dit niet ideaal. Het zou op zich wel kunnen maar omzetten naar gebruik van het geheugen voor opslag van de XML was iets handiger (zeker omdat het om relatief weinig data per run ging).

Hieronder de code voor een basis XML die zowel naar de browser gaat als naar een logfile:

// Set correct header
header('Content-Type: application/xml, charset=utf-8');

// Initiate XMLWriter
$xml = new XMLWriter();

// Create new xmlwriter using memory for string output
$xml->openMemory();

// Create document tag
$xml->startDocument('1.0', 'UTF-8');

// Create start element tag
$xml->startElement('test');

//  Write full element tag
$xml->writeElement('value', 'testwaarde');

// End current element
$xml->endElement();

// End current document
$xml->endDocument();

// Define logfile name
$filename = '/logs/' . date('Ymd_hm') . '.xml';

// Open file
$fp = fopen($filename, "w");

// Write memory output to file. The false boolean is to
// prevent XMLWriter from flushing the current buffer
fwrite($fp, $xml->outputMemory(false));

// Close the file
fclose($fp);

// Return the current buffer
echo $xml->outputMemory();

Dit is een redelijk kort samengevat voorbeeld en het kan altijd beter, netter en leuker maar het idee is duidelijk.

PHP memory limit stress test

In het vervolg op mijn eerdere bericht over een CPU stress test met PHP werd ook de vraag neergelegd om iets te maken wat de max uit het geheugen zou halen met PHP. Wederom volgde een korte brainstorm. Ik wilde voorkomen dat mijn memory test afhankelijk was van externe partijen (bijv. inlezen enorme datareeks of iets) en minimaal de processor zou belasten (om te voorkomen dat hij al tegen een CPU usage limiet aan zou lopen voor hij echt het geheugen vol kon stoppen). Het moest dus iets zijn wat iets simpels deed maar wel een monster ervan maakte voor het geheugen. Mijn oplossing is een scriptje wat éénmalig een string van 26 tekens maakt en die dan 5000 keer 5 keer achter elkaar plakt.

Even voor de lol de stringlengtes die PHP dus in het geheugen probeert te bewaren per for-loop (waarvan er 5000 zijn):
1x = 130 tekens
2x = 650 tekens
5x = 81250 tekens
10x = 253906250 tekens
15x = 793457031250 tekens

Etc. etc. Nog voor je bij een paarhonderd loops bent aangekomen vindt excel al dat de uitkomt “#GETAL!” is.

function generateData($loops)
{
	$chars = "ABCDEFGHJKLMNPQRSTUVWXYZ123456789";
	$i = 0;
	$string = null;
	
	while ($i <= 25) {
		$num = rand() % 33;
		$tmp = substr($chars, $num, 1);
		$string = $string . $tmp;
		$i++;
	}
	
	for ($i = 1; $i <= $loops; $i++) {
		$string = $string.$string.$string.$string.$string;
	}

	return $string;
}

$value = generateData(5000);
die('Wow, your memory is endless!');

Of download hem hier als kant-en-klaar PHP scriptje (tar file)

PHP CPU stress test

Recent vroeg iemand mij of ik even een scriptje in elkaar kon zetten wat een CPU tot de max kon drijven via PHP. Natuurlijk wil ik dat. Heel even voelt het dan net of je iets mag slopen. Na een korte brainstorm realiseerde ik me dat het helemaal niet zo’n ingewikkelde uitdaging ging worden als ik had gehoopt. Ik moest een proces hebben wat veel rekenkracht vroeg en ik moest het gewoon zo vaak mogelijk los laten op de processor als mogelijk in een zo kort mogelijk tijd. Het eerst wat in me opkwam was een loop met daarin een PI calculatie. Beetje zoeken op internet gaf me een nette PI calculatie code, daar nog wat omheen bakken en dan heb je iets als:

function bcpi($precision){
	bcscale($precision+6);
	$a = bcsqrt(2);
	$b = 0;
	$p = bcadd(2, $a);
	$i = 0;
	$count = ceil(log($precision+6)/log(2))-1;
	while($i < $count){
		$sqrt_a = bcsqrt($a);
		$a1 = $a;
		$a = bcdiv(bcadd($sqrt_a,bcdiv(1,$sqrt_a)),2);
		$b_up = bcmul($sqrt_a,bcadd(1,$b));
		$b_down = bcadd($a1,$b);
		$b = bcdiv($b_up, $b_down);
		$p_up = bcmul(bcmul($p,$b),bcadd(1,$a));
		$p_down = bcadd(1, $b);
		$p = bcdiv($p_up, $p_down);
		++$i;
	}
 
return bcadd($p,0,$precision);
}

for ($i = 1; $i <= 100; $i++) {
	bcpi(10000+$i);
}
die('Unbelievable, your CPU is a monster!');

Of download hem hier als kant-en-klaar PHP bestandje (rar file)

PHP & AJAX met Jquery tutorial

Recent hadden voor een project een creatieve oplossing gemaakt om bepaalde velden in het CMS standaard te “locken” en alleen mensen met een bepaalde user-role mochten de velden unlocken en bewerken. Denk hierbij aan velden als permanames. Omdat dit meer een stukje bescherming van gebruikers dan een echte security kwestie was (in dit geval) leek het ons wel leuk dit met een eenvoudige AJAX call te doen. Met Jquery zijn dit soort opties binnen het handbereik van iedere developer gekomen.

Erover nadenkend hoe lastig dit vroeger was en hoe leuk het nu was realiseerde ik me dat het misschien voor sommige mensen nog niet zo voor de hand liggend was. Daarom deze “super recht toe recht aan” tutorial / voorbeeldcode hoe je een simpele AJAX call naar een PHP script doet vanuit je HTML en het resultaat teruggooit naar de HTML.

De HTML code












Jquery AJAX call example

Klik op een woord hieronder om het resultaat van dat woord op te halen via AJAX en terug te geven als result.

  • Appels
  • Peren
  • Bananen
  • Kersen
  • Pinguins
<< empty >>

De PHP code

$fruits = array('Appels', 'Peren', 'Bananen', 'Kersen');

if(in_array($_POST['ajaxableVar'], $fruits)){
	echo 'Eet veel ' . $_POST['ajaxableVar'] . ' dat is gezond!';
	return;
}

echo $_POST['ajaxableVar'] . ' kun je niet eten!';
return;

Ditzelfde principe kun je ook neerzetten met JSON zodat je bijvoorbeeld een boolean terug kunt geven aan je Jquery code om bepaalde acties wel / niet uit te voeren. Eigenlijk zijn de mogelijkheden redelijk ruim.

* Let op! Het voorbeeld is ZEER basic en vereist wel enige configuratie en mutaties om hem veilig te maken voor je website maar als voorbeeld van het principe dekt het de lading prima.

Download hier de bestanden als .rar