Onko helppoa tapaa tehdä skriptiä Bashilla, PHP:llä tai Pythonilla, jolla voisi tarkistaa automaattisesti, onko HTML- tai PHP-koodissa virheitä? Tuntuu hieman tylsältä, kun tarkistan aina manuaalisesti koodin osoitteessa https://validator.w3.org/ . Ideana olisi harjoitella PHP-ohjelmointia ja olisi hyvä, jos skiptillä voisi tarkistaa, että PHP tuottaa validia koodia vaikka skriptin saamien muuttujien arvot vaihtelisivat. Tai en ainakaan keksinyt muuta tapaa validoita PHP-koodia.
HTML-validaattorin rajapintaa voi käyttää myös ohjelmallisesti. Jos käyttöä on paljon, validaattori kannattaa ehkä asentaa omalle palvelimelle dokumentaatiossa olevien ohjeiden mukaan.
<?php // Funktio HTML:n validointiin. function get_html_errors($data) { $context = stream_context_create(["http" => [ "method" => "POST", "header" => "Content-type: text/html; charset=UTF-8", "user_agent" => "PHP", "content" => $data, ]]); $url = "https://validator.w3.org/nu/?out=gnu"; return file_get_contents($url, false, $context); }
PHP-koodia sinänsä ei voi kovinkaan hyvin ”validoida”. Eihän siitä voi löytää edes bugeja luotettavasti, niin miten sitten koodin tulostetta voisi ennustaa? Eli tähän ainoa ratkaisu on se, että teet kattavan joukon omia testitapauksia ja käytät jotain yllä olevan tapaista testausmenetelmää. Koneellisessa testauksessa voisit tehdä testit esim. PHP-tiedostoihin ja ajaa ne sitten silmukassa. Esimerkki:
<?php require_once "get_html_errors.php"; ob_start(function($data) { $errors = get_html_errors($data); if (!$errors) { return "TEST OK!\n"; } $get = var_export($_GET, 1); $post = var_export($_POST, 1); return "TEST FAILED! $errors GET: $get POST: $post "; });
<?php $_GET = ["id" => "10"]; $_POST = ["jokin" => "arvo", "toinen" => "arvo"]; // $_SERVER = [...]; require_once "validointitestaus.php"; // ob_start, kuten yllä. require_once "projekti/testattava-sivu.php";
Selaimessa debug-vaiheessa näkyvään HTML:n validointiin voi myös hyödyntää tulosteen puskurointia. Esimerkiksi seuraava koodi sivun alussa alkaa tallentaa tuotettavaa sivua ja lopuksi validoi tuloksen ja tarvittaessa liittää sivulle virheilmoitukset. Tietenkin tällainen skripti kuormittaa omaa palvelinta ja validaattoria ja kannattaa siis pitää käytössä vain hetken kerrallaan.
<?php // Asetetaan tulosteen puskurointi niin, että sivun lopussa HTML validoidaan. require_once "get_html_errors.php"; ob_start(function($data) { $errors = get_html_errors($data); if (!$errors) { // Ei virheitä, ei lisätulostetta. return $data; } else { // On virheitä, näytetään ne. $errors = htmlspecialchars($errors); return $data . " <div style='position: fixed; left: 0; top: 0; right: 0; bottom: 0; overflow: scroll; background: white; color: black;'> <button onclick='this.parentNode.remove()'>Hide errors</button> <br><br> {$errors} <br><br> <button onclick='this.parentNode.remove()'>Hide errors</button> </div> "; } });
Sinänsä viisainta olisi vain opetella ohjelmointiperiaatteet, joilla saa tuotettua loogista HTML-koodia. Itselleni ei tule mieleen montakaan järkevää tilannetta, joissa muuttujien arvot PHP:ssä vaikuttaisivat siihen, tuleeko HTML:stä validia. Lähinnä ei-validia koodia voi saada aikaan, jos unohtaa htmlspecialchars-funktion tai sotkee lainausmerkkejä. Kannattaa ensin hoitaa varsinainen toiminnallinen PHP-koodi ja erikseen HTML:n tuottaminen, niin virheitä tulee vähemmän. Kannattaa myös pyrkiä echon käytöstä ja mieluummin kirjoittaa HTML-koodi suoraan ymmärrettävässä muodossa. Esimerkki:
<?php // Ensin haetaan tiedot. $asiat = hae_tietokannasta(); ?> <!-- Sitten tulee sivun sisältö. --> <h1>Muistilista</h1> <ul> <!-- ul on validi, li on validi, silmukka on selvästi li:n ympärillä. --> <?php foreach ($asiat as $asia): ?> <li><?= htmlspecialchars($asia) ?></li> <?php endforeach; ?> </ul>
Ja kohta tähän tulee joku kertomaan, että tuo koodi on ihan väärin tehty ja kunnon koodarit käyttävät jotain bloattia frameworkia. ;)
Ei tuohon vielä frameworkia tarvitse mutta muutama olio olisi tehnyt koodista vakuuttavamman. Ja on mielestäni aika pessimististä ja jopa käyttötarkoituksen vastaista nimetä validoinnin tekevä funktio get_html_errors:ksi. Sellaisen funktion voisi ennemmin kuvitella vaikka parsivan http-pyynnön tuloksesta ilmoitetut virheet.
Aihe on jo aika vanha, joten et voi enää vastata siihen.