Tunnus:

Salasana:

Uusi käyttäjä

Haku

Pikalinkit

Kesähaaste 2010

Paranna Morpion-pelin kansainvälisiä ennätyksiä!

Ohjeet | Nettipeli | Tuloslista

Putkaposti

Suunnittele tiedosto, josta tulee suuri ZIP-paketti!

Vastauksia: 32
Paras: 1158

Tehtävään...

Keskustelu

Siis mitä?? Missä kohtaa koodissa ilmenee muuttuja $_GET tai $_POST? (Nettisivut ja -ohjelmointi) lisää...


Koodivinkit: PHP: Sekalaiset: Oletusarvollinen taulukko

Kirjoittaja: map_ (30.12.2009)

PHP:ssa halutaan usein pitää E_NOTICE-virheilmoituksia päällä.

Eräs toisinaan ärsyttävä E_NOTICE-tason virhe on taulukon indeksoiminen olemattomalla avaimella. Esim. $_GET['sana'] aiheuttaa E_NOTICE-tason virheen, mikäli 'sana'-parametri jostain syystä puuttuu.

Suoraviivaisin tapa päästä näistä virheistä eroon on tehdä isset-tarkistuksia, kuten $sana = isset($_GET['sana']) ? $_GET['sana'] : '';, mutta tämä käy pidemmän päälle tylsäksi.

Listauksessa määritellään luokka DefaultingArrayObject, jonka ilmentymät toimivat kuin taulukot, mutta niitä voi aina indeksoida millä tahansa avaimella. Toteutus on suoraviivainen, sillä PHP:ssa on jo valmiina taulukon lailla käyttäytyvä luokka, ArrayObject, joka voidaan periä.

Lisäys: Eräs toinen ratkaisu esitettyyn ongelmaan on @-operaattori. Myöskään @$_GET['sana'] ei aiheuta virheilmoitusta, mutta ratkaisu ei ole ihan ongelmaton. Ks. tämän vinkin kommentit.

Listaukset

<?php
// DefaultingArrayObject.php

class DefaultingArrayObject extends ArrayObject
{
    protected
$_default;
   
    public function
__construct($array = array(), $default = null)
    {
       
parent::__construct($array);
       
$this->_default = $default;
    }
   
    public function
setDefault($default)
    {
       
$this->_default = $default;
    }
   
    public function
offsetGet($index)
    {
        return
$this->getWithDefault($index, $this->_default);
    }
   
    public function
getWithDefault($index, $customDefault)
    {
        if (
parent::offsetExists($index)) {
            return
parent::offsetGet($index);
        } else {
            return
$customDefault;
        }
    }
}

<?php
// Esimerkki
error_reporting(E_ALL | E_NOTICE);

require_once(
'DefaultingArrayObject.php');

$input = new DefaultingArrayObject($_GET);

if (
$input['sana'] == 'Firefly') {  // Ei E_NOTICEa vaikka 'sana' puuttuu
 
echo "Hyvä!";
}


Zeeli [31.12.2009 18:43:03]LainaaMuokkaa
Näppärä
janijohannes [11.02.2010 06:07:43]LainaaMuokkaa
Hmm...
Onhan tuo näppärä, mutta $_REQUEST-taulukko ajaa saman asian.
map_ [11.02.2010 10:36:31]LainaaMuokkaa
$_REQUEST kyllä yhdistää $_GETin, $_POSTin ja $_COOKIESin, mutta antaa edelleen E_NOTICEn kun sitä indeksoi olemattomalla avaimella.

echo $_REQUEST['asdasd'];

-->

Notice: Undefined index:  asd

punppis [12.03.2010 22:46:11]LainaaMuokkaa
Miksei voi vaan käyttää echo @$_REQUEST["nothing"]; ?
map_ [13.03.2010 00:32:09]LainaaMuokkaa
Kas, tuon operaattorin olemassaolo olikin unohtunut. Tästä vinkistähän tulikin suurin piirtein hyödytön :)
qeijo [26.03.2010 08:21:31]LainaaMuokkaa
if(isset($_POST[keijon_kalasaalis])){
$saalis = $_POST[keijon_kalasaalis];}
map_ [26.03.2010 11:24:27]LainaaMuokkaa
Juuri tuollaista pitkää ja toisteista muotoa oli tarkoitus välttää.
tsuriga [01.04.2010 04:47:18]LainaaMuokkaa
@-operaattori vain piilottaa virheen rumasti kun taas tällä saadaan palautettua ilman virhettä mikä tahansa haluttu arvo.
map_ [01.04.2010 14:34:21]LainaaMuokkaa
@ on kyllä yleisesti ottaen ruma piirre kielessä, ja useimmiten sitä ei kannata käyttää, mutta aiheuttaako se tässä tapauksessa mitään konkreettisia ongelmia?
tsuriga [13.04.2010 08:06:07]LainaaMuokkaa
Virhekontrollioperaattori on herkkä aiheuttamaan ennalta odottamattomia ongelmia. Mitä jos odotettua taulukkoa ei löydykään käytettävästä muuttujasta? @-operaattori ohittaa virheen huoletta kun taas oletusarvoista taulukkoa käytettäessä tulkki osaa tiedottaa tilanteesta. $_GET-taulukon ollessa kyseessä toki harvinaista, mutta särkinäisen PHP:n asennuksen tai eksentrisen sovelluksen tapauksessa mahdollista. Ongelmana tuossa voi siis olla debuggaus: "Osoiterivillä kyllä lukee news.php?id=2, mutta silti arvoa ei vain löydy... <monta tuntia myöhemmin> jaha, käyttämäni lisäpalikka on kutsunut unset($_GET)..."

Toisena huomiona mainittakoon manuaalin kommenteissa mainittu @-operaattorin harjoittama virhekäsittelijän kutsuminen error_levelin arvolla 0. Jos sovelluksessa on määritelty esimerkin #1 kaltainen virheenkäsittelijä niin sovellus tulostaa virhetilanteessa @-operaattoria käytettäessäkin virheviestin.
map_ [13.04.2010 11:37:51]LainaaMuokkaa
Hyviä pointteja. Itselläni on tapana määritellä vähän isompiin PHP-sovelluksiin aina virheenkäsittelijä, joka muuttaa virheet poikkeuksiksi. Käsittääkseni tilanteen voisi siis vielä korjata tarkistamalla käsittelijässä error_levelin nolluus, mutta, kuten sanottu, hyi.

ylläpito Antti Laaksonen, ulkoasu Otto Seiskari