Try ... catch en do while

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Roel -

Roel -

01/08/2011 23:44:33
Quote Anchor link
Hey!

Ik zit al een tijdje met een paar vragen. Ik weet een hele hoop over PHP (en dingen die daarmee te maken hebben) en over Java ook de basis dingen.

Nu snap ik een paar dingen niet. Om te beginnen de try ... catch functie.
Wat kun je hier precies mee? Ik heb begrepen dat dit is om fouten af te vangen, maar dit kun je toch ook gewoon met een if-statement doen, of denk ik hier verkeerd?

M'n andere vraag is, wanneer je nou precies een do while gebruikt.
Ik weet wanneer ik een for en while moet gebruiken en hoe ze werken, ook van do while. Toch snap ik niet waarom deze functie bestaat, op school is me verteld dat het soms handig kan zijn, maar er waren toen geen voorbeelden gegeven.

Hebben jullie antwoord op m'n vragen? Thanks :)
 
PHP hulp

PHP hulp

24/04/2024 21:04:15
 
The Force

The Force

02/08/2011 00:25:23
Quote Anchor link
Do while kan je gebruiken als je wil dat de code die erin staat minimaal één keer uitgevoerd moet worden. Een while loop wordt nul tot meerdere keren uitgevoerd. In de praktijk wordt het nauwelijks gebruikt.

Een functie kan op meerdere manieren aangeven dat er iets fout is gegaan. Zo kan je bijvoorbeeld false teruggeven. Je kan dan met een if/else constructie dit afvangen. Het kan ook zijn dat de functie een exceptie geeft. Dit kan je niet afvangen met een if/else constructie aangezien de exceptie optreedt voordat de functie iets returnt. Je krijgt dan ook de foutmelding "Uncaught Exception: ..." met de exceptie erbij. Je wil natuurlijk niet graag dat een gebruiker een dergelijke PHP foutmelding voor zijn neus krijgt. Als je (net als in een if/else constructie) deze fout goed wilt afhandelen dan kan je hem afvangen met een try ... catch blok.

Voorbeeld:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
<?php
class Links {

    private $baseUrl;
    
    public function __construct() {
        $this->$baseUrl = 'http://test.com';
    }

        
    /**
     * Generating normal URLs (like index.php?page=5)
     *
     * @param int $page
     * @param string $linkname
     * @return string
     */

    public function generateLink($page, $linkname) {
        if(is_numeric($page)) {
            return '<a href="' . $this->baseUrl . '?page=$page">' . $linkname . '</a>';
        }
else {
            throw new Exception("Parameter 'page' must be an integer.", E_ERROR);
        }
    }
}

?>


Dit is een klasse puur bedoeld als voorbeeld. De functie genereert een URL gebaseerd op een paginanummer en de linknaam. Hier moet je dus met een try/catch blok de exceptie afvangen.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
<?php
$paginate
= new Paginate();
try {
    $paginate->generateLink(1, 'De eerste pagina'); //Dit gaat goed.
    $paginate->generateLink('fout', 'Test'); //Dit levert een exceptie op.
    $paginate->generateLink(3, 'De derde pagina'); //Dit wordt niet meer uitgevoerd want als er een exceptie optreedt dan gaat ie meteen naar de catch.
} catch(Exception $e) {
    echo 'Woeps er is iets fout gegaan. Het bericht is' . $e->getMessage();
    echo 'Start de foutafhandeling!';
}

?>


Wanneer moet je wat gebruiken?
Gebruik false in return als het een normaal scenario is dat een bepaald iets niet goed is. Gebruik excepties bij onverwachte fouten die niet horen te gebeuren. Soms is het een beetje een grijs gebied wanneer je wat moet gebruiken.

Vanwege PHP's verleden worden de fouten die optreden niet als excepties 'gethrowed' maar krijg je gewoon een foutmelding die eventueel uit te schakelen is middels error reporting. Dat is waarom je try/catch niet veel ziet. Alleen nieuwe OO libraries van PHP gebruiken excepties zoals ze horen. Doordat PHP zelf niet goed met excepties omgaat gebruiken ook veel gebruikers excepties niet zoals ze in de meeste programmeertalen gebruikt worden. Zie http://php.net/manual/en/language.exceptions.php voor meer informatie.
 
Roel -

Roel -

02/08/2011 19:59:40
Quote Anchor link
Bedankt voor je duidelijk en uitgebreide uitleg. Ik snap de try ... catch functie nu een stuk beter.
Heb je misschien een voorbeeld van een situatie waarin een do while wél nuttig kan zijn?
Gewijzigd op 03/08/2011 17:05:28 door Roel -
 
Roel -

Roel -

03/08/2011 20:38:22
Quote Anchor link
Bump!
 
Kees Schepers

kees Schepers

03/08/2011 22:43:08
Quote Anchor link
Een voorbeeldje, het kan natuurlijk ook op andere manieren gefixed worden.

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
<?php
$groups
= array(
    'guest',
    'controller',
    'admin'
);

$user = new user();

do {
    $user->addGroup($group);

}
while( ($group = $user->isAllowed(next($group))) !== false);
?>


Hierdoor wordt de gast rol altijd toegevoegd aan de user. Weet alleen niet of de next constructie zo goed werkt. Maar zoals gezegd in de praktijk wordt hij niet veel gebruikt. Ik zie het overigens wel soms voorbij komen in Zend Framework.

In Java heb je trouwens ook nog try { } catch () { } finally { } om je aangemaakt resources e.d. in op te ruimen, dit heb je in PHP niet.
 
Roel -

Roel -

04/08/2011 20:13:49
Quote Anchor link
Hmm. Ik vraag me nog steeds af WAAROM je het zou willen.
Ik snap precies hoe de functie werkt, maar ik kan er met m'n verstand niet bij waarom?
 
The Force

The Force

04/08/2011 20:24:20
Quote Anchor link
Als je dus code minimaal 1x wil uitvoeren. En mocht je iets als dit tegen komen:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
<?php

//Statements hier.

while(conditie) {
    //Dezelfde statements hier.
}
?>


Dan moet je of de while conditie aanpassen of je maakt er een do while van en je laat de conditie hetzelfde.

Wanneer gebruik je het nu echt? Niet, eigenlijk. Je kan de conditie van de while eigenlijk altijd zo formuleren dat je het met een while afkan. Terwijl je een while altijd (0 tot * keer) kan gebruiken, is de do while vrij specifiek (1 tot * keer). Als je al code hebt die 1 tot * keer uitgevoerd moet worden dan schrijven mensen het uit gewenning vaak alsnog met while.
 
Roel -

Roel -

04/08/2011 21:13:49
Quote Anchor link
Op school is mij verteld dat het soms handig kan zijn. Dan vraag ik me wel af waarin.
Bij een virusscanner of zo? Ik snap gewoon totaal niet waarom zo'n functie dan überhaupt bestaat.
 
Roel -

Roel -

06/08/2011 19:29:49
Quote Anchor link
PHPhulp, of PHPzwijg?
 
Noppes Homeland

Noppes Homeland

06/08/2011 19:46:58
Quote Anchor link
Waarom zit je te bumpen, je hebt je antwoorden toch gekregen?

En letwel dat do while en try catch geen functies zijn, maar "semantieke constructies"
 
Dos Moonen

Dos Moonen

06/08/2011 20:14:35
Quote Anchor link
Bij het genereren van een unieke code voor een actievatie of lisentie systeem of iets dergelijks kan do-while handig zijn:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
<?php

do
{
    $uniek = een_of_andere_functie();
    $query = mysql_query("SELECT id FROM tabel where veld = '".$uniek."'", $conn);
}

while(mysql_num_rows($query)); // do het nog een keer als er een rij gevonden is

// we zijn uit de do-while, dus deze code bestaat (hoogst waarschijnlijk, denk aan race condities) nog niet

mysql_query("INSERT into tabel (veld) VALUES ('".$uniek."')", $conn);

?>
 
Roel -

Roel -

06/08/2011 20:18:26
Quote Anchor link
Thx voor je voorbeeld Dos.
 
Eric Wagener

Eric Wagener

09/08/2011 16:15:10
Quote Anchor link
Een ander voorbeeld waar een do - while nuttig kan zijn is als je de gegevens uit de database alleen in de header van je rapport wil laten zien. Dus als je bijvoorbeeld een tabel bestellingen hebt en een tabel bestelregels.
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
<?
// query: SELECT bst.id, reg.artikel
//        FROM bestellingen bst, bestelregels reg
//        WHERE bst.id = reg.id

...
if ($rij = $result->fetch_array()){
    print "{$rij["id"]} <br>"; // header
    do {
        print "{$rij["artikel"]} <br>"; // regels
    }
while ($rij = $result->fetch_array());
?>

Maar natuurlijk zijn er vele manieren om dit op te lossen.
Gewijzigd op 09/08/2011 16:15:52 door Eric Wagener
 
Kees Schepers

kees Schepers

09/08/2011 17:49:38
Quote Anchor link
Ik heb de do {} while() vandaag toevallig nog gebruikt in een Zend Framework applicatie! Omdat ik er nu niet bij kan zal ik morgen weleens een code snippet posten/twitteren!

Toevoeging op 10/08/2011 09:51:01:

Zoals belooft een stukje code, ik heb even de hele functie gepakt zodat eventuele geintreseerde de context ook begrijpen :) Het is een frontcontroller plugin die het e.e.a. met navigatie doet :)

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
<?php
    public function dispatchLoopStartup(Zend_Controller_Request_Abstract $request)
    {

        $file = APPLICATION_PATH . '/configs/navigation.xml';

        if (!file_exists($file)) {
            throw new BestBuy_Exception('Navigation.xml not found in configs directory.');
        }


        $config = new Zend_Config_Xml($file, 'nav');

        $navigation = new Zend_Navigation($config);

        $this->_addClassToContainer('link', $navigation);

        $bootstrap = Zend_Controller_Front::getInstance()->getParam('bootstrap');
        $layout = $bootstrap->getResource('layout');

        /**
         * Uses Pike_Menu to check permissions based on more roles. (ZF 1.11 doesn't support
         * multiple roles checking)
         *
         */

        $view = $layout->getView();
        $view->navigation()
            ->
PikeMenu($navigation)
            ->
setACL(Zend_Registry::get('acl'))
            ->
setRoles(Zend_Auth::getInstance()->getIdentity()->getRoles());

        /**
         * Check if the resource name of the current page has child pages and add these to
         * the submenu. If it hasn't child pages look in has parent.
         */

        $resource = implode('_', array(
            $request->getModuleName(),
            $request->getControllerName(),
            $request->getActionName()
        ));

        
        do {
            $page = $navigation->findBy('resource', $resource);
            if ($page instanceof Zend_Navigation_Page && $page->hasPages()) {
                $view->submenu = $page;
            }
elseif($page instanceof Zend_Navigation_Page) {
                $resource = $page->getParent()->resource;
                if (null === $resource)
                    break;
            }
else {
                break; //$page is null there is no submenu
            }
        }
while ($view->submenu === null);
    }

?>
 
Roel -

Roel -

04/09/2011 18:15:10
Quote Anchor link
Thx. Misschien een beetje een late reactie, maar ik had hem nog niet gelezen!
 



Overzicht Reageren

 
 

Om de gebruiksvriendelijkheid van onze website en diensten te optimaliseren maken wij gebruik van cookies. Deze cookies gebruiken wij voor functionaliteiten, analytische gegevens en marketing doeleinden. U vindt meer informatie in onze privacy statement.