Kirjautuminen

Haku

Tehtävät

Keskustelu: Ohjelmointikysymykset: Kuinka voin tarkistaa kotikoneella olevaa PHP-koodia ohjelmallisesti? (HTML)

Jaska [03.01.2019 18:36:13]

#

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.

Metabolix [04.01.2019 19:23:20]

#

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. ;)

The Alchemist [06.01.2019 15:10:51]

#

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.

Vastaus

Aihe on jo aika vanha, joten et voi enää vastata siihen.

Tietoa sivustosta