Tein seuraavan näköisen funktion:
<?php function input($method, $name) { $method = "_" . $method; $value = (isset(${$method}[$name]) ? htmlspecialchars(${$method}[$name]) : null); return $value; } echo input("GET", "nimi");
Tuon funktion tarkotuksena on se, että sillä pitäisi pystyä lukemaan
php:n GET, POST, SERVER, SESSION, COOKIE -taulukoista jne... alkioita, kun funktiolle annetaan taulukon nimi sekä alkion avain. Tarkoituksena on siis se, että funktio tarkistaa automaattisesti syötteen olemassa olon sekä puhdistaan sen xss-aukoista.
Ongelma on kuintenkin se, ettei tuo toimi. Tarkoitan siis sitä, ettei tuo funktio palauta kuin tyhjää. Outoa on se, kun testasin tuon funktion sisällä olevaa koodia ilman funktio-rakennetta, niin homma pelitti. Voipi olla, että kyseessä on taas joku hyvin yksinkertainen juttu, joka ei vaan ole osunut silmään.
Ongelma on se, että asetat funktion parametrinä olevan muuttujan arvon. Muuta homma vaikka näin:
<?php function input($method, $name) { $method2 = "_" . $method; $value = (isset(${$method2}[$name]) ? htmlspecialchars(${$method2}[$name]) : null); return $value; } echo input("GET", "nimi");
Eipä tuokaan toimi sen paremmin eli samaa tyhjän tulostamista edelleenkin...
edit.
Käytin tuohon input-funktion palautusarvoon var_dump-funktiota ja sen mukaan tuon funktion palauttama arvo on NULL. Tämän pitäisi selvästi tarkoittaa sitä, että tuota alkiota ei löydy taulukosta ja siksi value-muuttuja saa arvokseen NULL. Tämä kuitenkaan ei voi olla mahdollista, sillä olen itse antanut sen urlissa...
Testataanpa:
<?php $get = "_GET"; var_dump($_GET); // array(1) { ["juttu"]=> string(1) "moi" } var_dump($$get); // array(1) { ["juttu"]=> string(1) "moi" } var_dump($GLOBALS[$get]); // array(1) { ["juttu"]=> string(1) "moi" } function tmp() { $get = "_GET"; var_dump($_GET); // array(1) { ["juttu"]=> string(1) "moi" } var_dump($$get); // Notice: Undefined variable: _GET in ... var_dump($GLOBALS[$get]); // array(1) { ["juttu"]=> string(1) "moi" } } tmp();
Tuloksista voi päätellä, että vaikka $_GET on superglobaali, $$get ei toimi funktion sisällä. Sen sijaan $GLOBALS-taulukosta kohta _GET yhä löytyy.
Lähestymistavassasi on kuitenkin kaksi ongelmaa: Kun käytät mielivaltaisia tekstivakioita, kirjoitusvirheiden riski kasvaa etkä saa tästä muuta ilmoitusta kuin tuon pienen noticen. Lisäksi funktiosi palauttaa valmiiksi html-muotoista tekstiä, jota ei ole lainkaan käytännöllistä jatkokäsitellä (esim. tallentaa tietokantaan). Funktio htmlspecialchars kannattaa pitää visusti tulostuksen yhteydessä, jos ei ole erittäin hyvää syytä tehdä toisin.
Metabolixin vinkkiä soveltamalla minulla alkuperäinen homma toimii näin:
function input($method, $name) { $method = "_" . $method; $value = (isset($GLOBALS[$method][$name]) ? htmlspecialchars($GLOBALS[$method][$name]) : null); return $value; }
Aihe on jo aika vanha, joten et voi enää vastata siihen.