Uitleg van de PHP code
Schakel uit veiligheid alle errors uit. De wiki is niet geintreseert in de PHP errors. Daarnaast willen wij de hacker geen gevoelige informatie geven.
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
2
3
4
5
6
7
8
9
10
11
12
13
<?php
if($link = mysql_connect('localhost','root',''))
{
if(!mysql_select_db('test',$link))
{
$link = false;
}
}
if(!$link)
{
$error = 'Unable to connect towards the database';
}
?>
if($link = mysql_connect('localhost','root',''))
{
if(!mysql_select_db('test',$link))
{
$link = false;
}
}
if(!$link)
{
$error = 'Unable to connect towards the database';
}
?>
Maak verbinding met de Mysql server. Wij slaan de resultaat op in een var. Daarna kijken wij of we de database naam kunnen selecteren. Gaat dat niet dan maken wij de resource ($link) ongeldig.
Wanneer het mislukt setten wij een error.
Code (php)
Defineer een lege array waar de data in komt. Om te voorkomen dat de wiki die de wikiping verstuurd ongeldige data mee stuurt (Tags die niet worden ondersteund) gaan wij deze tags filteren. Het is nog wel mogelijk om html en andere gevaarlijke dingen mee te sturen. Die worden tijdens het uitlezen verwijderd.
Wat blijkt wanneer je door middel van een HTTP post request gegevens verstuurd kan je in PHP deze gegevens niet in de $_POST array vinden. Maar hoe moet het dan anders? Ik heb met dit probleem echt 4 dagen zitten te klooien en omdat ik geen Internet verbinding had kon ik het even niet snel vragen op een internet forum. Na uren de handleiding door lezen kwam ik er nog steeds niet achter. En op het moment dat ik de moed wou opgeven kwam ik achter deze functie.
En toen kwam ik er achter dat $HTTP_RAW_POST_DATA bestond en dat daar de gegevens instaan als je door middel van HTTP Post request data verstuurd.
Nu controleren wij of deze variabele bestaat zo niet dan stoppen wij er mee . En uiteraard geven wij een error op het einde. Zie einde van het script.
Code (php)
1
2
3
4
5
6
7
2
3
4
5
6
7
<?php
//we could not use SimpleXML due no support for PHP 4
$xml_praser = xml_parser_create();
//tell the vars to the xml phrasers
xml_parse_into_struct($xml_praser,$HTTP_RAW_POST_DATA,$xml_keys,$xml_index);
xml_parser_free($xml_praser);
?>
//we could not use SimpleXML due no support for PHP 4
$xml_praser = xml_parser_create();
//tell the vars to the xml phrasers
xml_parse_into_struct($xml_praser,$HTTP_RAW_POST_DATA,$xml_keys,$xml_index);
xml_parser_free($xml_praser);
?>
Nu komt het grootste probleem. De Post request bestaat uit een XML bestand en direct een XML bestand invoegen in een database is niet slim. We zullen deze gegevens eerst moeten verwerken.
Hoewel ik deze script op een PHP 5 server heb geschreven moest hij werken op een PHP4 server. Hier door kon ik geen gebruik maken van de Simple XML extensie.
De PHP DOM functies was ook niet ideaal omdat daar net alles wordt omgezet van functies naar classes. Conclusie dit was de meest ideale cross "server" oplossing.
Wat doen we hier.
[ol]
We maken een XML praser aan We vertellen PHP dat hij de var $HTTP_RAW_POST_DATA moet verwerken naar 2 vars. 1 met de waardes en de andere met de key namen. Daarna moet hij het verwerken[/ol]
Hoe het exact werkt weet ik niet maar het werkt. Vergeet niet dat alle array keys UPPERCASE zijn.
Nu komt werkelijk het verwerken van de gegevens.
Wij hebben nu 2 arrays. 1 array ($xml_keys) bevat een $array met alle benodige gegevens. Hellaas zijn daar alle XML tag namen vervangen door een integer. Waar wij hellaas niets mee kunnen. We zouden dan een onhandig loop constructie moeten doen.
Gelukkig hebben wij daarbij ook nog een andere array namelijk de $xml_index. In deze array zijn alle tags op "alfabet" gesorteerd en alle keys met de zelfde naam zijn onder een andere array gevoegd. Dit maakt alles nu 100 keer simpeler.
Wat gaan wij doen. Wij zoeken naar alle keys die de waarde "MEMBER" zouden hebben in de XML document.
Code (php)
Wij doen dat simpel gewoon met een foreach loop. Nu komt het leuke. Als wij alle indexen met de waardes van "member" zullen gebruiken hebben wij ook de sluit tags en de cdata tags. En die moeten wij niet. Dus wij kijken doormiddel van een if statment of de type "open" is.
Maar nu komt het volgende probleem zoals je zit staan de gegevens van de naam van de waarde niet in de MEMBER tag maar in een subtag. Dus wij tellen er bij. Controleren of de waarde in de $allowed_keys staat. Zo ja dan voegen wij hem toe. Zo niet. Gewoon doorgaan
Is het waar dan stoppen wij de waarde van de name in de array als "key" en de waarde van de value tag ($index +3) als "waarde" in de array.
Na afloop van de deze script krijg je dit als antwoord
Code (php)
1
2
3
4
5
6
7
8
9
2
3
4
5
6
7
8
9
Var $data:
array(
'tag' => 'CodeLabs',
'url' => 'http://www.codelabs.nl/CodeLabs',
'wiki' => 'CodeLabs',
'author' => 'EriS',
'authorpage' => 'http://www.codelabs.nl/EriS',
'history' => 'http://www.codelabs.nl/CodeLabs/revisions'
)
array(
'tag' => 'CodeLabs',
'url' => 'http://www.codelabs.nl/CodeLabs',
'wiki' => 'CodeLabs',
'author' => 'EriS',
'authorpage' => 'http://www.codelabs.nl/EriS',
'history' => 'http://www.codelabs.nl/CodeLabs/revisions'
)
Nu is het simpel trappen alle gegevens in een mysql database.
Kijk hier voor de tabel structuur (SQL code).
Dit doen wij heel simpel
Wij kijken eerst of er wel iets instaat anders hoeven wij ook niets in te voeren.
Daarna controleren wij of wij een database verbinding hebben zo niet gaat het verhaaltje niet door en maken wij alleen errors.
Code (php)
1
2
3
4
5
6
7
8
9
10
2
3
4
5
6
7
8
9
10
<?
$sql = 'insert into wikiping set';
//create sql QUERY
foreach($data as $label => $value)
{
$sql.= ' '.$label.'="'.mysql_real_escape_string($value,$link).'",';
}
//add a date
$sql.= ' date_received = now()';
?>
$sql = 'insert into wikiping set';
//create sql QUERY
foreach($data as $label => $value)
{
$sql.= ' '.$label.'="'.mysql_real_escape_string($value,$link).'",';
}
//add a date
$sql.= ' date_received = now()';
?>
INSERT INTO wikiping set lijk mij duidelijk. Wij willen de gegevens in de tabel wikiping trappen.
Daarna lopen wij door de data array waarbij wij de key en waarde gaan gebruiken om de SQL op te bouwen. Omdat wij hebben gecontroleerd dat de key van geldig is het niet nodig om onze database te beschremen voor mysql injection. Voor de waarde moet dat uiteraard wel. We zouden addslashes() kunnen gebruiken maar mysql_real_escape_string is veiliger. Uiteraard heeft deze wel een waarde en de database verbinding nodig. Wanneer wij klaar zijn met de array voegen wij als laatst de toevoeg datum toe. Die wordt niet met de XML request mee gezonden. Hier zorgen wij dat wij op soorteren op laatst toegevoegd. Bij het uit lezen. Omdat er maximaal 1 misschien 2 seconden verschil is het niet zo erg dat het de server datum is. Andere tijdzones hebben maar pech gehad.
Wij voegen het nu in de database en vangen eventueel de error en geven een error als het mislukt. Als het goed gaat melden wij niets en ronden wij de script af.
Nu komt nog een error van de eerste controle
Code (php)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<?php
if (isset($error))
{
echo '<?xml version="1.0" encoding="utf-8"?'.">\n";
echo "<response>\n";
echo "<error>1</error>\n";
echo "<message>$error</message>\n";
echo "</response>";
}
else
{
echo '<?xml version="1.0" encoding="utf-8"?'.">\n";
echo "<response>\n";
echo "<error>0</error>\n";
echo "</response>";
}
?>
Wij geven nu een bericht terug. Met daarin de resultaat.
if (isset($error))
{
echo '<?xml version="1.0" encoding="utf-8"?'.">\n";
echo "<response>\n";
echo "<error>1</error>\n";
echo "<message>$error</message>\n";
echo "</response>";
}
else
{
echo '<?xml version="1.0" encoding="utf-8"?'.">\n";
echo "<response>\n";
echo "<error>0</error>\n";
echo "</response>";
}
?>
Wij geven nu een bericht terug. Met daarin de resultaat.
« vorige pagina | volgende pagina »
Inhoudsopgave
- Wiki ping
- Wat is een wikiping
- XML bestand
- De script
- Uitleg van de PHP code
- Uitlezen
- Tabel Structuur
- Ondersteuning van wiki's
- Waarom zo uitgebreid