[php] variablen variabel naar functie sturen

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • Martine
  • Registratie: Mei 2002
  • Niet online
Omdat ik er niet helemaal meer uit kom heb ik de onderstaande testomgeving gemaakt. Ik zal het zo goed mogelijk proberen uit te leggen.

De functie bloemen moet twee waarden krijgen, alleen wil ik die waarden dynamisch toevoegen. Voor de functie bloemen zijn het er twee, maar het kan voorkomen als de volgende functie veel meer waarden nodig heeft.

De array $data wordt automatisch aangemaakt en gevuld, het gaat er nu om als de betreffende functie met zoveel waarden wordt aangeroepen als de array $data bevat.

Hoe krijg ik zoiets voor elkaar?

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
    function bloemen($var1, $var2) {
        $out .= "<br>var1: ".$var1;
        $out .= "<br>var2: ".$var2;
        
        return $out;
        
    }
    
    $data[] = "some value";
    $data[] = "kleding";
    
    $name = "bloemen";
    
    echo $name("foo","bar");



Als ik het bovenstaande wist, was ik al een heel eind verder.

Eigenlijk gaat het erom als ik de functienaam en de waarden dynamisch in een andere functie kan stoppen, zo dus;

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
function test($id) {
  
  // hier moet ik de functienaam weten - foo dus - deze wordt hieronder
  // aangeroepen met de waarden var1 en var2. echter, deze waarden
  // kunnen er ook meer zijn.

  echo $id(??); // op de ?? moeten dus de waarden var1 en var2 komen.
}

$functienaam = "foo";

echo test($functienaam("var1", "var2")); // don't work 


Hierboven werkt natuurlijk niet, het loopt stuk op de tweede haakjes, hoe los ik het op? 8)7

Acties:
  • 0 Henk 'm!

  • ACM
  • Registratie: Januari 2000
  • Niet online

ACM

Software Architect

Werkt hier

(jarig!)
En waarom geef je niet gewoon de $data-array mee als parameter?

Acties:
  • 0 Henk 'm!

  • BtM909
  • Registratie: Juni 2000
  • Niet online

BtM909

Watch out Guys...

Ace of Base vs Charli XCX - All That She Boom Claps (RMT) | Clean Bandit vs Galantis - I'd Rather Be You (RMT)
You've moved up on my notch-list. You have 1 notch
I have a black belt in Kung Flu.


Acties:
  • 0 Henk 'm!

  • Martine
  • Registratie: Mei 2002
  • Niet online
Nou, het kan ook voorkomen als ik die functie elders ga aanroepen, dan moet ik alle functies gaan ombouwen en dat is nogal een flinke klus wat ik eigenlijk wil voorkomen.

//edit: bedankt BtM909, maar call_user_func_array() is niet echt wat ik zoek. hiermee wordt het probleem niet opgelost als een functie meerdere argumenten wil ontvangen.

[ Voor 33% gewijzigd door Martine op 30-10-2007 17:28 ]


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

PHP:
1
2
3
4
5
6
7
8
function foo()
{
    print_r(func_get_args());
}

foo();
foo(1, 2);
foo("aap", "noot", "mies");


icm de tip van BtM909 moet je er toch wel uit kunnen komen dacht ik zo...

[ Voor 25% gewijzigd door .oisyn op 30-10-2007 17:43 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • ERIKvanPAASSEN
  • Registratie: September 2006
  • Laatst online: 20-09 10:12

ERIKvanPAASSEN

Bug Killer

EDIT: Ik heb weer niet goed gelezen. 8)7

[ Voor 85% gewijzigd door ERIKvanPAASSEN op 30-10-2007 17:55 ]


Acties:
  • 0 Henk 'm!

  • BtM909
  • Registratie: Juni 2000
  • Niet online

BtM909

Watch out Guys...

.oisyn schreef op dinsdag 30 oktober 2007 @ 17:28:
PHP:
1
2
3
4
function foo()
{
    print_r(func_get_args());
}

icm de tip van BtM909 moet je er toch wel uit kunnen komen dacht ik zo...
Ik ging er idd vanuit dat de TS deze zelf kon vinden ;)

Ace of Base vs Charli XCX - All That She Boom Claps (RMT) | Clean Bandit vs Galantis - I'd Rather Be You (RMT)
You've moved up on my notch-list. You have 1 notch
I have a black belt in Kung Flu.


Acties:
  • 0 Henk 'm!

  • Martine
  • Registratie: Mei 2002
  • Niet online
Heel kort gezegd: Ja, had ik al gefunden... hoofdpijn slaat toe, snap niet als dit niet gewoon werkt... $#%RE% 7(8)7

Acties:
  • 0 Henk 'm!

  • FragFrog
  • Registratie: September 2001
  • Laatst online: 09:34
Martine schreef op dinsdag 30 oktober 2007 @ 17:19:
De array $data wordt automatisch aangemaakt en gevuld, het gaat er nu om als de betreffende functie met zoveel waarden wordt aangeroepen als de array $data bevat.

Hoe krijg ik zoiets voor elkaar?

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
    function bloemen($var1, $var2) {
        $out .= "<br>var1: ".$var1;
        $out .= "<br>var2: ".$var2;
        
        return $out;
        
    }
    
    $data[] = "some value";
    $data[] = "kleding";
    
    $name = "bloemen";
    
    echo $name("foo","bar");
Ik krijg het gevoel dat je veel te moeilijk zit te denken. Als je een callbackfunctie wilt die elke waarde in een array eventueel met wat meuk ertussen optelt kun je daar legio simpele technieken voor gebruiken. foreach() is mijn favoriet, array_map of array_callback bijvoorbeeld werken ook prima gok ik:
PHP:
1
2
3
4
5
$data[] = "foo";
$data[] = "bar";

foreach($data as $item)
  $bloemen .= '<br>var' . ++$i . ': '. $item;


Dit doet exact hetzelfde als jou script, alleen dan voor zoveel entries als je maar wilt.
PHP:
1
2
3
4
5
6
7
function test($id) {
  echo $id(??); // op de ?? moeten dus de waarden var1 en var2 komen.
}

$functienaam = "foo";

echo test($functienaam("var1", "var2")); // don't work 
Die tweede echo is overbodig - je retouneert niets dus is er ook niets te echo'en. Wederom krijg ik de indruk dat je 'maar wat aan het prutsen' (TM) bent, correct me if I'm wrong.

[ Site ] [ twitch ] [ jijbuis ]


Acties:
  • 0 Henk 'm!

  • Martine
  • Registratie: Mei 2002
  • Niet online
FragFrog schreef op dinsdag 30 oktober 2007 @ 18:07:
Dit doet exact hetzelfde als jou script, alleen dan voor zoveel entries als je maar wilt.
Het gaat er niet om als de output hetzelfde is, de hele rambam moet in een functie.
Die tweede echo is overbodig - je retouneert niets dus is er ook niets te echo'en. Wederom krijg ik de indruk dat je 'maar wat aan het prutsen' (TM) bent, correct me if I'm wrong.
Als jij dat zegt 'zal dat wel zo zijn' (TM) :o
Je hebt gelijk, die andere echo had een return moeten zijn, goh, foutje? :P

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

Martine schreef op dinsdag 30 oktober 2007 @ 18:07:
Heel kort gezegd: Ja, had ik al gefunden... hoofdpijn slaat toe, snap niet als dit niet gewoon werkt... $#%RE% 7(8)7
Wat is je code dan nu precies, en waarom werkt dat niet? Want aangaande je topicstart snap ik echt niet wat er dan fout gaat.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Martine
  • Registratie: Mei 2002
  • Niet online
Nogmaals,... alleen dan beter! :)

Stel; op de frontpage van een website wordt bij elke pageview een functie aangeroepen, hierin zit een redelijk zware mysql query om een brok informatie op het scherm te krijgen.

Nu wil ik ongeacht welke of wat voor functie het is, opslaan in een bestand. Zolang er geen update komt kan het bestand ongewijzigd blijven. Op deze manier wordt de belasting op de server verminderd.

Deze functie wordt momenteel gebruikt, wat er in deze functie zit is in principe onbelangrijk.
PHP:
1
2
3
4
5
// de huidige manier van aanroepen
echo SomeFunction($_GET['id'], $foo, $bar);

// nu wil ik de output van deze functie in een cache bestand opslaan
echo FileCache(SomeFunction($_GET['id'], $foo, $bar));


De bedoeling is dat het cache bestand de naam SomeFunction krijgt, het lullig is; hoe roep SomeFunction MET dezelfde waarden weer aan, dus met $_GET['id'], $foo, $bar. Dit moet gebeuren op regel 25.

Dat is het hele probleem, ik wil niet gruwlijk veel in mijn code aanpassen om een functie in een cache bestand te laten schrijven.

Het probleem is natuurlijk het aanroepen van SomeFunction in de functie FileCache, want geen enkele functie is gelijk en maakt gebruik van dezelfde input. Dit moet dus dusdanig gemaakt worden zodat ik alles erheen kan sturen, en het gewoon in een cache bestandje opslaan.


De functies dit ik gebruik voor het cachen van een output
PHP:
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
    // wordt gebruikt om de output van include(file) naar een string om te zetten
    function GetIncludeContent($file) {
        if (is_file($file)) {
            ob_start();
            include $file;
            $contents = ob_get_contents();
            ob_end_clean();
            return $contents;
        }
        return false;
    }
    
    
    // voor het aanroepen of wegschrijven van een cache bestand
    function FileCache($name, $a="read") {
        global $path;
        
        if (!file_exists($path."/inc_cache/".$name) && $a == "read") {
            FileCache($name, "write");
        }
        elseif (!file_exists($path."/inc_cache/".$name) && $a != "read") {
            ob_start();
            
            // functie aanroepen en de output in het cache bestand proppen
            echo $name();
            
            $output = ob_get_contents();
            ob_end_clean();
            
            $file = fopen($path."/inc_cache/".$name, "w");
            fputs($file, $output);
            fclose($file);
        }
        
        return GetIncludeContent($path."/inc_cache/".$name);
    }

Acties:
  • 0 Henk 'm!

  • Raynman
  • Registratie: Augustus 2004
  • Laatst online: 15:51
Kun je FileCache() niet een derde (optionele) parameter geven? Dat is dan een array met bijv. $_GET['id'], $foo, $bar en dan doe je call_user_func($name, $params).

Of is je probleem dan dat je $_GET['id'], $foo, $bar weer in een array moet gooien; wil je dat op een of andere manier automatiseren?

Acties:
  • 0 Henk 'm!

  • Martine
  • Registratie: Mei 2002
  • Niet online
Als ik die waarden in die functie aanroep met func_get_args() hoe krijg ik ze dan zo, als ze de daadwerkelijke functie aanroepen?

PHP:
1
2
3
4
5
  // hoe verander ik in de functie
  echo $name();

  // in
  echo SomeFunction($_GET['id'], $foo, $bar);

[ Voor 32% gewijzigd door Martine op 30-10-2007 21:13 ]


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

Euhm, ik denk niet dat je je realiseert wat een aanroep als a(b()) eigenlijk doet. Hij roept niet a() aan met als parameter de string "b()" oid. Hij roept éérst b() aan, en het resultaat van die functie (dus wat b returnt) gebruikt hij om naar a() te sturen. Er is vanuit a() dus geen enkele manier om erachter te komen hoe dat argument tot stand is gekomen.
PHP:
1
2
3
4
5
6
7
8
9
10
11
function b()
{
    return 1;
}

function a($var)
{
    echo $var;
}

a(b());

$var in a() is gelijk aan 1, omdat het resultaat van b() 1 was. $var is niet b(), b() wordt éérst aangeroepen, dan pas a().

Ik snap nu wat je probeert te doen, maar dat kan gewoonweg niet op de manier waarop je het probeert te doen. Dat kan alleen als je de hele call in een string zet (dus: a("b()" of a("b", param1, param2)), maar ik gok dat dat ook niet is wat je wilt. Ik denk dat een log-call doen in elke functie waarvoor je het wilt implementeren het meest praktisch is.

[ Voor 5% gewijzigd door .oisyn op 30-10-2007 21:44 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Martine
  • Registratie: Mei 2002
  • Niet online
Ik denk dat een log-call doen in elke functie waarvoor je het wilt implementeren het meest praktisch is.
Oki, das duidelijk, maar wat bedoel je precies met een log-call?

Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

een call is een aanroep, je log is het bestandje waar je het in wilt opslaan. Dus in het begin van elke functie die je wilt loggen doe je een aanroep naar een functie die die log-entry toevoegt.

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Martine
  • Registratie: Mei 2002
  • Niet online
Zo heb ik het opgelost, niet helemaal mooi, maar zo moet het maar. Als iemand een beter idee heeft, dan hoor ik het graag!

PHP:
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
    function FileCache($name, $data, $a="read") {
        global $path;
        
        if (!file_exists($path."/inc_cache/".$name) && $a == "read") {
            FileCache($name, $data, "write");
        }
        elseif (!file_exists($path."/inc_cache/".$name) && $a != "read") {
            ob_start();
            
            // functie aanroepen en de output in het cache bestand proppen
            echo $name($data);
            
            $output = ob_get_contents();
            ob_end_clean();
            
            $file = fopen($path."/inc_cache/".$name, "w");
            fputs($file, $output);
            fclose($file);
        }
        
        return GetIncludeContent($path."/inc_cache/".$name);
    }
    
    function bloemen($data) {
        $out .= "var1: ".$data->var1;
        $out .= "var2: ".$data->var2;
        $out .= "var3: ".$data->var3;
        
        return $out;
    }
    
    $data->var1 = "var nr. 1";
    $data->var2 = "var nr. 2";
    
        // aanroepen zonder cache
    echo bloemen($data);
    
        // aanroepen met cache
    echo FileCache("bloemen", $data);

Acties:
  • 0 Henk 'm!

  • FragFrog
  • Registratie: September 2001
  • Laatst online: 09:34
Martine schreef op dinsdag 30 oktober 2007 @ 23:04:
Zo heb ik het opgelost, niet helemaal mooi, maar zo moet het maar. Als iemand een beter idee heeft, dan hoor ik het graag!

PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
        elseif (!file_exists($path."/inc_cache/".$name) && $a != "read") {
            ob_start();
            
            // functie aanroepen en de output in het cache bestand proppen
            echo $name($data);
            
            $output = ob_get_contents();
            ob_end_clean();
            
            $file = fopen($path."/inc_cache/".$name, "w");
            fputs($file, $output);
            fclose($file);
        }
Dit zou ik dan sowieso al vervangen met
PHP:
1
file_put_contents($path."/inc_cache/".$name, $name($data));

er van uitgaande dat je geen ranzige echo's midden in je functies hebt zitten :+

Sowieso vraag ik me een beetje af of je nu wel handig bezig bent. Elke functie apart gaan cachen betekend sowieso al dat je al je functiecalls moet aanpassen wat niet erg handig is met een grote site en daarnaast ben je vele malen simpeler en sneller af met het cachen van je complete output - een goed framework kan dit zo voor je regelen.

[ Site ] [ twitch ] [ jijbuis ]


Acties:
  • 0 Henk 'm!

  • frickY
  • Registratie: Juli 2001
  • Laatst online: 18-09 14:42
Martine schreef op dinsdag 30 oktober 2007 @ 19:51:
PHP:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
function FileCache($functioncall) {
    if(file_exists($functioncall . '.cache')) {
        return file_get_cntents($functioncall . '.cache');
    } else {
        // eval = evil. .maar in dit geval wel 'handig'
       // je kunt de $functioncall ook parsen en de functienaam en argumenten in call_user_func stoppen
        eval('$return = ' .  $functioncall);
        file_set_cntents($functioncall . '.cache', $return);
        return $return;
    }
}

// nu wil ik de output van deze functie in een cache bestand opslaan
echo FileCache("SomeFunction($_GET['id'], $foo, $bar)");
:?

Wellicht dat MemCached iets voor je is?

[ Voor 23% gewijzigd door frickY op 30-10-2007 23:44 ]


Acties:
  • 0 Henk 'm!

  • .oisyn
  • Registratie: September 2000
  • Laatst online: 03:42

.oisyn

Moderator Devschuur®

Demotivational Speaker

Martine schreef op dinsdag 30 oktober 2007 @ 23:04:
Zo heb ik het opgelost, niet helemaal mooi, maar zo moet het maar. Als iemand een beter idee heeft, dan hoor ik het graag!
Waarom dan niet de func_get_args() erin verwerken, zodat je niet met arrays hoeft te werken? Oftewel, waar BtM909 en ik het in het begin van de draad al over hadden. De parameters pass je gewoon zoals je normaal doet, in FileCache vraag je de parameters op met func_get_args(). Daar haal je het eerste element vanaf omdat dat je functienaam is, de parameters houd je over. Vervolgens roep je die functie aan met call_user_func_array.

Dan zit je nog met die read/write param aan FileCache(), maar daar kun je net zo goed verschillende functies voor maken: FileCacheRead en FileCacheWrite (en evt. nog een FileCache een van de twee aanroept afhankelijk van of de file al bestaat)

[ Voor 47% gewijzigd door .oisyn op 31-10-2007 00:17 ]

Give a man a game and he'll have fun for a day. Teach a man to make games and he'll never have fun again.


Acties:
  • 0 Henk 'm!

  • Martine
  • Registratie: Mei 2002
  • Niet online
FragFrog schreef op dinsdag 30 oktober 2007 @ 23:29:
Dit zou ik dan sowieso al vervangen met
PHP:
1
file_put_contents($path."/inc_cache/".$name, $name($data));

er van uitgaande dat je geen ranzige echo's midden in je functies hebt zitten
Da's php5 en dat heb ik, nog niet, op mijn servertje draaien.
.oisyn schreef op woensdag 31 oktober 2007 @ 00:12:
[...]

Waarom dan niet de func_get_args() erin verwerken, zodat je niet met arrays hoeft te werken? ...
... Vervolgens roep je die functie aan met call_user_func_array.
Dan kom ik hier op uit .oisyn, bedankt voor het geweldige denkwerk!

PHP:
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
    function FileCache() {
        global $path;
        
        $arr = func_get_args();
        if (!file_exists($path."/inc_cache/".$arr[0].".php"))
            return call_user_func_array("FileCacheWrite", $arr);
        else
            return GetIncludeContent($path."/inc_cache/".$arr[0].".php");
    }
    
    function FileCacheWrite() {
        global $path;
        
        $arr = func_get_args();
        $name = array_shift($arr);
        
        ob_start();
        
        echo call_user_func_array($name, $arr);
        
        $output = ob_get_contents();
        ob_end_clean();
        
        $file = fopen($path."/inc_cache/".$name.".php", "w");
        fputs($file, $output);
        fclose($file);
        
        return GetIncludeContent($path."/inc_cache/".$name.".php");
    }


Nu kan ik de functie 'bloemen' aanroepen op de onderstaande manieren.

PHP:
1
2
3
4
5
6
7
8
9
  // gewoon aanroepen, zonder cache
  echo bloemen("foo", "bar", "getaway car")

  // aanroepen met cache, als het bestand niet bestaat wordt
  // het aangemaakt en direct weergegeven
  echo FileCache("bloemen", "foo", "bar", "getaway car");

  // onder een input in de database, om de cache te vernieuwen
  echo FileCacheWrite("bloemen", "foo", "bar", "getaway car");


Allemaal bedankt voor de medewerking, mede dankzij jullie reacties, tips en ideeen heb ik nu een geweldige(!!!) cache functie. _/-\o_

// edit; als iemand nog betere ideeen heeft, schroom niet en post gerust een reply.

Acties:
  • 0 Henk 'm!

  • mocean
  • Registratie: November 2000
  • Laatst online: 04-09 10:34
Ik zou eens kijken naar Smarty

Goede uitgebreide template engine, die op 2 levels caching standaard ondersteund. (compiled templates en output cache van complete pagina's).

Koop of verkoop je webshop: ecquisition.com


Acties:
  • 0 Henk 'm!

  • Grijze Vos
  • Registratie: December 2002
  • Laatst online: 28-02 22:17
mocean schreef op woensdag 31 oktober 2007 @ 17:42:
Ik zou eens kijken naar Smarty

Goede uitgebreide template engine, die op 2 levels caching standaard ondersteund. (compiled templates en output cache van complete pagina's).
Martine schreef op dinsdag 30 oktober 2007 @ 19:51:
Dat is het hele probleem, ik wil niet gruwlijk veel in mijn code aanpassen om een functie in een cache bestand te laten schrijven.
Misschien wil je het topic even doorlezen voordat je smarty gaat lopen prediken...

Op zoek naar een nieuwe collega, .NET webdev, voornamelijk productontwikkeling. DM voor meer info

Pagina: 1