Kun je vanuit function php meer variabelen overnemen?

Overzicht Reageren

Sponsored by: Vacatures door Monsterboard

Yoeri Achterbergen

Yoeri Achterbergen

09/02/2018 22:53:19
Quote Anchor link
Hallo,


Kun je als je een functie hebt aangemaakt in een php file meerdere variabelen aanroepen?

Bijvoorbeeld

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
<?php
function schedule(){
    date_default_timezone_set('Europe/Amsterdam');
    $weekdag = (int) date('w');
        switch ($weekdag) {
            case
0:  // zondag
            $today = "zondag";
            $next_day = "maandag"
            break;
            

            case
1:  // maandag
            $today = "maandag";
            $next_day = "dinsdag"
            break;
            
            
            case
2:  // dinsdag
            $today = "dinsdag";
            $next_day = "woensdag"
            break;
            

            case
3:  // woensdag
            $today = "woensdag";
            $next_day = "donderdag"
            break;
            
            
            case
1:  // donderdag
            $today = "donderdag";
            $next_day = "vrijdag"
            break;
            
            case
1:  // vrijdag
            $today = "vrijdag";
            $next_day = "zaterdag"
            break;
            
            case
1:  // zaterdag
            $today = "zaterdag";
            $next_day = "zondag"
            break;
            
    }

?>


Nu wil ik deze functie en de 2 variabelen $today en $next afzonderlijk kunnen aanroepen.
Nu heb ik dit geprobeerd met parameters alleen werkt het alleen als beide variabelen worden aangeroepen en niet los
 
PHP hulp

PHP hulp

29/09/2020 10:32:19
 
Ben van Velzen

Ben van Velzen

09/02/2018 23:22:27
Quote Anchor link
Als ik je vraag goed begrijp wil je beide variabelen toegankelijk hebben buiten je functie. Dit kun je op 2 manieren doen. Je kunt een array returnen uit je functie, bijvoorbeeld als volgt:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
<?php
// hier je functie
return array('today' => $today, 'next_day' => $next_day);
?>

Je kunt het ook via parameters doen, maar dan zul je ze by reference moeten maken:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
<?php
function schedule(&$today, &$next_day) {
// je functie
}
?>

Je kunt de functie dan aanroepen als schedule($today, $next_day).
Gewijzigd op 09/02/2018 23:28:30 door Ben van Velzen
 
Thomas van den Heuvel

Thomas van den Heuvel

09/02/2018 23:58:23
Quote Anchor link
In de oorspronkelijke code staat wel 4 x "case 1"? Waarschijnlijk wordt bij de laatste 3 gevallen respectievelijk case 4, 5 en 6 bedoeld?

Daanaast bevat de functie nogal veel redundante informatie, want uit de huidige $weekdag kun je heel gemakkelijk de volgende dag afleiden, dit is ($weekdag + 1) % 7.

Tevens: engelse en nederlandse namen / naamgeving door elkaar: *brrr*.

Ook is het misschien handiger om een (taalspecifieke) mapping te maken van weekdag naar dagnaam, dan kun je simpelweg met datums/weekdagen blijven rekenen, in plaats van tekstlabels, bijvoorbeeld via een array ofzo.

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
$days
=> array(
    0 => 'zondag',
    1 => 'maandag',
    2 => 'dinsdag',
    3 => 'etc',
    4 => 'etc',
    5 => 'etc',
    6 => 'etc'
);
$weekDay = date('w');
echo 'vandaag is het '.$days[$weekDay].', morgen is het '.($days[($weekDay+1)%7]);
?>
Gewijzigd op 10/02/2018 02:10:51 door Thomas van den Heuvel
 
Yoeri Achterbergen

Yoeri Achterbergen

10/02/2018 20:42:56
Quote Anchor link
Dank voor jullie reactie.

Ik heb het zo gedaan:

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
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
<?php
function time_schedule(){

    date_default_timezone_set('Europe/Amsterdam');
    $weekdag = (int) date('w');

        switch ($weekdag) {
        
            case
0:  // zondag
            $today = "<tr><td>Vandaag gesloten</td></tr>";
            $time_table = "
            <tr><td>Maandag</td><td>:</td><td>Gesloten</td></tr>
            <tr><td>Dinsdag</td><td>:</td><td>10:00 - 18:00</td></tr>
            <tr><td>Woensdag</td><td>:</td><td>10:00 - 18:00</td></tr>
            <tr><td>Donderdag</td><td>:</td><td>10:00 - 18:00</td></tr>
            <tr><td>Vrijdag</td><td>:</td><td>10:00 - 18:00</td></tr>
            <tr><td>Zaterdag</td><td>:</td><td>10:00 - 16:00</td></tr>
            "
;
            break;
    
            case
1:  // maandag
            $today = "<tr><td>Vandaag gesloten</td></tr>";
            $time_table = "
            <tr><td>Dinsdag</td><td>:</td><td>10:00 - 18:00</td></tr>
            <tr><td>Woensdag</td><td>:</td><td>10:00 - 18:00</td></tr>
            <tr><td>Donderdag</td><td>:</td><td>10:00 - 18:00</td></tr>
            <tr><td>Vrijdag</td><td>:</td><td>10:00 - 18:00</td></tr>
            <tr><td>Zaterdag</td><td>:</td><td>10:00 - 16:00</td></tr>
            <tr><td>Zondag</td><td>:</td><td>Gesloten</td></tr>
            "
;
            break;    
    
            case
2:  // dinsdag    
            $today = "<tr><td>Vandaag open tot 18:00</td></tr>";
            $time_table = "
            <tr><td>Woensdag</td><td>:</td><td>10:00 - 18:00</td></tr>
            <tr><td>Donderdag</td><td>:</td><td>10:00 - 18:00</td></tr>
            <tr><td>Vrijdag</td><td>:</td><td>10:00 - 18:00</td></tr>
            <tr><td>Zaterdag</td><td>:</td><td>10:00 - 16:00</td></tr>
            <tr><td>Zondag</td><td>:</td><td>Gesloten</td></tr>
            <tr><td>Maandag</td><td>:</td><td>Gesloten</td></tr>
            "
;
            break;    
    
            case
3:  // woensdag    
            $today = "<tr><td>Vandaag open tot 18:00</td></tr>";
            $time_table = "
            <tr><td>Donderdag</td><td>:</td><td>10:00 - 18:00</td></tr>
            <tr><td>Vrijdag</td><td>:</td><td>10:00 - 18:00</td></tr>
            <tr><td>Zaterdag</td><td>:</td><td>10:00 - 16:00</td></tr>
            <tr><td>Zondag</td><td>:</td><td>Gesloten</td></tr>
            <tr><td>Maandag</td><td>:</td><td>Gesloten</td></tr>
            <tr><td>Dinsdag</td><td>:</td><td>10:00 - 18:00</td></tr>
            "
;
            break;    
    
            case
4:  // donderdag    
            $today = "<tr><td>Vandaag open tot 18:00</td></tr>";
            $time_table = "
            <tr><td>Vrijdag</td><td>:</td><td>10:00 - 18:00</td></tr>
            <tr><td>Zaterdag</td><td>:</td><td>10:00 - 16:00</td></tr>
            <tr><td>Zondag</td><td>:</td><td>Gesloten</td></tr>
            <tr><td>Maandag</td><td>:</td><td>Gesloten</td></tr>
            <tr><td>Dinsdag</td><td>:</td><td>10:00 - 18:00</td></tr>
            <tr><td>Woensdag</td><td>:</td><td>10:00 - 18:00</td></tr>
            "
;
            break;    
    
            case
5:  // vrijdag    
            $today = "<tr><td>Vandaag open tot 18:00</td></tr>";
            $time_table = "
            <tr><td>Zaterdag</td><td>:</td><td>10:00 - 16:00</td></tr>
            <tr><td>Zondag</td><td>:</td><td>Gesloten</td></tr>
            <tr><td>Maandag</td><td>:</td><td>Gesloten</td></tr>
            <tr><td>Dinsdag</td><td>:</td><td>10:00 - 18:00</td></tr>
            <tr><td>Woensdag</td><td>:</td><td>10:00 - 18:00</td></tr>
            <tr><td>Donderdag</td><td>:</td><td>10:00 - 18:00</td></tr>
            "
;
            break;    
    
            case
6:  // zaterdag    
            $today = "<tr><td>Vandaag open tot 16:00</td></tr>";
            $time_table = "
            <tr><td>Zondag</td><td>:</td><td>Gesloten</td></tr>
            <tr><td>Maandag</td><td>:</td><td>Gesloten</td></tr>
            <tr><td>Dinsdag</td><td>:</td><td>10:00 - 18:00</td></tr>
            <tr><td>Woensdag</td><td>:</td><td>10:00 - 18:00</td></tr>
            <tr><td>Donderdag</td><td>:</td><td>10:00 - 18:00</td></tr>
            <tr><td>Vrijdag</td><td>:</td><td>10:00 - 18:00</td></tr>
            "
;
            break;
    }


return array('today' => $today, 'time_table' => $time_table);
}

?>


Vervolgens aanroepen in andere file:

Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
<?php
echo time_schedule()["today"];

//en ergens anders in de file
echo time_schedule()["time_table"];

?>


Of zouden jullie het op een andere manier doen?
 
Thomas van den Heuvel

Thomas van den Heuvel

10/02/2018 22:54:27
Quote Anchor link
Ik zou dit zeker anders doen.

Allereerst - die tijdszone-instelling hoort niet echt thuis in een functie wat mij betreft. Dit is een instelling die een applicatie-wijde impact heeft en die wil je dus niet ergens halverwege je code activeren, vooral als het moment waarop dit gebeurt kan verschillen.

Tijdsberekeningen kunnen mogelijk voor en na deze aanroep verschillen, je wilt simpelweg geen ruimte creëren dat (de aanroep van) zo'n setting (op die plaats) op deze manier invloed heeft op dat soort zaken, zorg dus dat deze instelling meteen bij de initialisatie van alle andere applicatie-wijde variabelen/instellingen geschiedt.

Dan definieer je tig keer dezelfde openings- en sluitingstijden in plakken HTML (don't repeat yourself). Wat nu als er een openingstijd verandert? Je moet dit dan dus ook meerdere keren aanpassen met het gevaar dat je hierbij typefouten maakt of wat dan ook. Niet praktisch en foutgevoelig. Definieer deze informatie éénmalig:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
<?php
$openingTimes
= array(
    0 => array('opening' => false, 'closed' => false),      // sunday
    1 => array('opening' => false, 'closed' => false),      // monday
    2 => array('opening' => '10:00', 'closed' => '18:00'),  // tuesday
    3 => array('opening' => '10:00', 'closed' => '18:00'),  // wednesday
    4 => array('opening' => '10:00', 'closed' => '18:00'),  // thursday
    5 => array('opening' => '10:00', 'closed' => '18:00'),  // friday
    6 => array('opening' => '10:00', 'closed' => '16:00')   // saturday
);
?>

Op deze manier krijgt je informatie ook betekenis.

Vervolgens lijkt het mij niet zo handig om elke keer de begindag van de openingstijden af te laten hangen van de huidige dag van de week - dan wordt elke dag de informatie in een andere volgorde weergegeven, wat nogal verwarrend kan zijn. Je zou er ook voor kunnen kiezen om deze openingstijden altijd in dezelfde volgorde af te drukken en dan de huidige dag te highlighten. Beide kun je in ieder geval met een for-loop doen:
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
<?php
$weekDay
= date('w');

// starts with today
for ($i=0; $i < 7; $i++) {
    $currentDay = ($weekDay + $i) % 7;
    echo $weekDays[$currentDay].'<br>';
}


echo '<hr>';

// start on a fixed day, e.g. monday
$startDay = 1;
for ($i = $startDay; $i < $startDay + 7; $i++) {
    $currentDay = $i % 7;
    echo $weekDays[$currentDay].'<br>';
}

?>

En onderscheid zou je kunnen maken op grond van $weekDay:
Code (php)
PHP script in nieuw venster Selecteer het PHP script
1
2
3
4
5
6
7
8
9
10
11
<?php
// ...
if ($weekDay == $currentDay) {
    // some other formatting, to highlight the current day
    echo '<b>'.$weekDays[$currentDay].'</b><br>';
}
else {
    // any other day
    echo $weekDays[$currentDay].'<br>';
}

// ...
?>

En dan zijn er natuurlijk nog uitzonderingen zoals feestdagen et cetera.

Zorg in ieder geval dat je maar één bron voor dit soort type informatie hebt zodat als hier iets in wijzigt je dit ook maar op één plek hoeft aan te passen.

EDIT: en met dit alles kun je dus met een iets intelligentere for-loop in één keer alle relevante informatie precies op die manier weergeven zoals jij wilt, hier heb je dus niet tig plakken met ongeveer dezelfde (betekenisloze en foutgevoelige) HTML voor nodig. Dit wordt dan vervolgens zoiets:
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
<table><?php
    for ($i=0; $i < 7; $i++) {
        $currentDay = ($weekDay + $i) % 7;
        $opening = $openingTimes[$currentDay]['opening'];
        $closing = $openingTimes[$currentDay]['closed'];
        ?>
<tr>
            <td><?php echo $weekDays[$currentDay] ?></td>
            <td>:</td>
            <td><?php
            if ($opening === false) {
                // voor de goede orde zou "Gesloten" ook uit een taalbestand moeten komen natuurlijk
                ?>
Gesloten<?php
            } else {
                ?>
<?php echo $opening ?> - <?php echo $closing ?><?php
            }
            ?>
</td>
        </tr><?php
    }
?>
</table>

EDIT #2: ik zou dit geheel ook altijd sluitend maken, dus geef ook <table></table> tags mee in de functie zelf, je wilt niet op verschillende plaatsen (mogelijk ook in verschillende bestanden) uit gaan zoeken waar alle HTML vandaan komt. Als het nodig is dat de table af en toe anders opgemaakt wordt geef de functie dan een parameter mee waarin je een CSS-class definieert zodat je dit dynamisch kunt regelen.

EDIT #3: FUNCTIES zijn er trouwens ook voor om hergebruikt te worden, hoe vaak geef je deze informatie weer? De vraag is dus eigenlijk ook: hoort dit uberhaupt in een functie thuis :p.
Gewijzigd op 10/02/2018 23:13:31 door Thomas van den Heuvel
 
Rob Doemaarwat

Rob Doemaarwat

11/02/2018 10:19:09
Quote Anchor link
@EDIT #3: Soms vind ik het wel lekker om een hele partij "bagger" (code die eigenlijk niet zo heel veel spannends doet, maar vooral veel ruimte inneemt) weg te stoppen in een functie. In de "main flow" van code waar je dan mee bezig was blijft er dan 1 regel over met een duidelijke functienaam, waardoor je precies snapt wat er gebeurt (zonder het overzicht kwijt te raken).

Daarnaast kun je vaak al aan een stuk code "ruiken" dat je die "later" nog wel eens vanaf een andere plek nodig kunt gaan hebben (deze openingstijden staan bijvoorbeeld in de footer, maar komen zometeen ook expliciet op de "Contact" pagina). Door het dan op voorhand al in een functie te parkeren hoef je niet later weer met chirurgische precisie de code die je wilt gaan hergebruiken er uit te snijden (om alsnog in een functie onder te brengen).
 
Thomas van den Heuvel

Thomas van den Heuvel

11/02/2018 15:57:02
Quote Anchor link
Rob Doemaarwat op 11/02/2018 10:19:09:
Daarnaast kun je vaak al aan een stuk code "ruiken" dat je die "later" nog wel eens vanaf een andere plek nodig kunt gaan hebben (deze openingstijden staan bijvoorbeeld in de footer, maar komen zometeen ook expliciet op de "Contact" pagina).

Dat is dan doorgaans ook het moment dat je er een functie van maakt :). Met die logica kun je eigenlijk alles op voorhand in functies stoppen, want stel dat je het ooit nog ergens nodig hebt...

Rob Doemaarwat op 11/02/2018 10:19:09:
Door het dan op voorhand al in een functie te parkeren hoef je niet later weer met chirurgische precisie de code die je wilt gaan hergebruiken er uit te snijden (om alsnog in een functie onder te brengen).

Als dat "met chirurgische precisie uitsnijden" nodig zou zijn dan zegt dat natuurlijk ook iets over de manier waarop je programmeert. Je zou van nature (of je nu met functies werkt of niet) dingen bij elkaar moeten zetten, moeten annoteren et cetera. Code zou altijd geschreven moeten zijn zodat iemand anders hier direct chocola van kan maken. Als niemand behalve de oorspronkelijke auteur hiermee uit de voeten kan omdat deze de rode draad/draden kent dan is er meer mis :p (en het zou onfortuinlijk zijn als die persoon dan op een goede dag onder de tram belandt).

Als je gewoon een beetje netjes programmeert komt dit neer op een passage knippen en plakken in een functie-body, eventueel met wat toegevoegde parameters. Dit hoeft echt niet veel moeite te kosten tenzij je code al een chaos was.

Wanneer je iets vaker dan één keer gebruikt is een functie gehonoreerd, in wezen volg je dan gewoon het DRY-principe.
 
Willem vp

Willem vp

13/02/2018 00:59:09
Quote Anchor link
Thomas van den Heuvel op 10/02/2018 22:54:27:
EDIT #3: FUNCTIES zijn er trouwens ook voor om hergebruikt te worden, hoe vaak geef je deze informatie weer? De vraag is dus eigenlijk ook: hoort dit uberhaupt in een functie thuis :p.

Dit ben ik niet volledig met je eens. Functies dienen niet alleen voor hergebruik, maar ook voor complexiteitsreductie en/of overzicht. (Dat noemt men ook wel "gestructureerd programmeren")

Op mijn werk geldt als vuistregel dat wanneer code groter wordt dan op 1 A4'tje past, je die code in een subroutine moet onderbrengen. Dat heeft meteen een zelfdocumenterend effect, want uiteraard bedenk je een passende naam voor een dergelijke subroutine. Bovendien zijn kleinere functies eenvoudiger te testen op correcte werking dan grote.

Probeer je eens in te denken hoeveel moeite het kost om 500 regels code door te moeten lezen om erachter te komen wat die code doet(*). Ga je dat opbreken in subroutines van gemiddeld 50-60 regels, dan krijg je een hoofd-subroutine met een stuk of 10 aanroepen van andere subroutines en weet je in hoofdlijnen al wat de code doet als je alleen die 10 regeltjes hebt gelezen.

Overigens lukt het me in de praktijk ook niet altijd om functies binnen een regel of 50 te houden, gewoonweg omdat het code is die eigenlijk niet is op te splitsen in meerdere subroutines. Maar zelfs dat geval is voldaan aan een van de basisconcepten van gestructureerd programmeren: een subroutine hoort slechts 1 taak uit te voeren.

(*) Nee, commentaar is daar niet voor bedoeld. ;-)
 
Thomas van den Heuvel

Thomas van den Heuvel

13/02/2018 01:31:27
Quote Anchor link
In die vuistregel wordt ook (ten minste) een tradeoff gemaakt. Op het moment dat er ergens een foutje in de code geslopen is bij gebruikmaking van zo'n opdeling moet je ook heel dat kruimelpad volgen. Zo'n topdown aanpak introduceert nog steeds overhead als je eens een keer de diepte in moet :p. En dan heb je nog een bijkomende factor: al die onderdelen hebben misschien afhankelijkheden met andere onderdelen, dus als je je specifieke probleem repareert trek je misschien iets anders omver (mogelijk zonder dat je er erg in hebt).

En wat je zelf zegt: het dient voor complexiteitsreductie. Ik zou een schema met openingstijden nu niet direct complex noemen.

Niet alle stukken functionaliteit -zoals je zelf ook aangeeft- lenen zich voor deze opzet, het in dat geval op die manier opdelen van functionaliteit maakt iets juist complexer, in plaats van simpeler. Mogelijk valt er ook niet zoveel te splitsen, wat zou je in een schema met openingstijden willen opdelen zonder dat het geheel langgerekter wordt? En wat als dit in een uitgebreider stuk functionaliteit (een pagina voor het weergeven van openingstijden) uitgeschreven staat die al specifiek voor dat doel (het weergeven van openingstijden) ingericht is? Dan staat het in principe al op de goede plek zou ik zeggen. Sterker nog: zolang het maar op een bepaalde manier gevangen is in een zekere structuur -en dit hoeft niet per se een functie te zijn- ben je al een heel eind op de goede weg.

Ook kun je niet op voorhand een oplossingsstrategie inzetten, dat is zoiets als zeggen dat een hamer per definitie hét stuk gereedschap is voor elke klus.

Ik denk dat we beiden naar hetzelfde doel streven, maar in beide gevallen is dit niet het doel an sich.
 



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.