[PHP] dynamische hoeveelheid argumenten doorsturen

Pagina: 1
Acties:

Onderwerpen


Acties:
  • 0 Henk 'm!

  • pat42
  • Registratie: Maart 2006
  • Niet online

pat42

» lurkt

Topicstarter
Hoi medetweakers. Ik probeer een dynamisch aantal argumenten door te sturen naar een andere functie. Het laat zich denk ik het beste uitleggen met deze code:
PHP:
1
2
3
4
5
6
7
class mymysqli_stmt extends mysqli_stmt {
    public function bind_param($types, $argument1,  $argument2,  $argument3, ...) {
        //doe iets met de data
        parent::bind_param($types, , $argument1,  $argument2,  $argument3, ...);
        //doe nog meer met de data
    }
}

Het probleem zit hem in de hoeveelheid argumenten die bind_param accepteert: het eerste argument is vast, en daarna komen er nog een willekeurig aantal (voor elke variable die je wilt binden).

Nou kan je alle argumenten wel opvangen met func_get_args() dus daar zit het probleem niet. Maar hoe speel ik ze door aan de parent?
PHP:
1
2
$array = array_slice(func_get_args(),1); //krijg alle optionele argumenten
parent::bind_param($types, $array); //stuur ze in een array door naar een andere functie

Het bovenstaande werkt niet, want ik moet de argumenten echt als losse argumenten meegeven aan de parent. Uit elkaar halen en ze aan elkaar plakken ((string) '"arg1", "arg2", "arg3"') werkt natuurlijk ook niet omdat hij het dan als een enkele string ziet. Op google vond ik geen oplossing, en ook op GoT kwam ik niets tegen.
Iemand een idee?

Acties:
  • 0 Henk 'm!

  • eamelink
  • Registratie: Juni 2001
  • Niet online

eamelink

Droptikkels

call_user_func_array() :)

Acties:
  • 0 Henk 'm!

  • pat42
  • Registratie: Maart 2006
  • Niet online

pat42

» lurkt

Topicstarter
Held _/-\o_
Dat lijkt inderdaad precies te zijn wat ik zoek!

Acties:
  • 0 Henk 'm!

  • CodeCaster
  • Registratie: Juni 2003
  • Niet online

CodeCaster

Can I get uhm...

Ik bemerk meestal dat je probleem ergens anders ligt wanneer er functies als call_user_func() en eval() om de hoek moeten komen kijken om je probleem op te lossen.

Klopt de aanvoer van je data wel? Kan datgene wat je in die functie uitvoert niet op een andere manier?

https://oneerlijkewoz.nl
Op papier is hij aan het tekenen, maar in de praktijk...


Acties:
  • 0 Henk 'm!

  • eamelink
  • Registratie: Juni 2001
  • Niet online

eamelink

Droptikkels

In het code voorbeeld dat gegeven is lijkt mij een dergelijke functie absoluut niet 'verkeerd' :)

Acties:
  • 0 Henk 'm!

  • Cartman!
  • Registratie: April 2000
  • Niet online
Ik pak meestal een array of object die ik meegeef als argument dan omdat t voor mn gevoel netter is.

PHP:
1
$this->functionName('type', array('arg1' => 'val1', 'arg2' => 'val2'));

Acties:
  • 0 Henk 'm!

  • Janoz
  • Registratie: Oktober 2000
  • Laatst online: 21-09 02:21

Janoz

Moderator Devschuur®

!litemod

Met Cartman! en CodeCaster.

Een veel nettere oplossing zou zijn dat je je methoden/functies een array als parameter mee laat geven. Voor de handigheid kun je daarnaast een methode toevoegen die ook een variabel aantal parameters accepteerd, maar die roept dan vervolgens gewoon de array variant aan.

Ken Thompson's famous line from V6 UNIX is equaly applicable to this post:
'You are not expected to understand this'


Acties:
  • 0 Henk 'm!

  • jbdeiman
  • Registratie: September 2008
  • Laatst online: 21:23
Ik vraag me af of jij met call_user_func_array() bereikt wat je wilt. Het aantal argumenten in de array moet wel overeenkomen met de items (en in de volgorde) zoals jij ze hebt staan:
PHP:
1
2
3
4
5
6
7
8
9
<?php
class mymysqli_stmt extends mysqli_stmt {
    public function bind_param($types, $argument1,  $argument2,  $argument3, ...) {
        //doe iets met de data
        parent::bind_param($types, , $argument1,  $argument2,  $argument3, ...);
        //doe nog meer met de data
    }
}
?>

De array moet dan ook zijn (puur voor de argumenten)
PHP:
1
2
3
<?php
array('arg1' => 'waarde', 'arg2' => 'waarde', 'arg3' => 'waarde');
?>

Alleen waarde 1 en 2 meegeven kan niet, ook mag het aantal waarden in de array nooit groter zijn dan het aantal mogelijkheden in de functie aanroep. Je kan dus op deze manier niet zorgen voor een dynamische functie.

Wat volgens mij toch de handigste oplossing is, is werken met een array, zie bijv hier:
PHP:
1
2
3
4
5
6
7
8
9
10
11
<?php
/* just explaining how to call mysqli_stmt_bind_param with a parameter array */

$sql_link = mysqli_connect('localhost', 'my_user', 'my_password', 'world');
$type = "isssi";
$param = array("5", "File Description", "File Title", "Original Name", time());
$sql = "INSERT INTO file_detail (file_id, file_description, file_title, file_original_name, file_upload_date) VALUES (?, ?, ?, ?, ?)";
$sql_stmt = mysqli_prepare ($sql_link, $sql);
call_user_func_array('mysqli_stmt_bind_param', array_merge (array($sql_stmt, $type), $param);
mysqli_stmt_execute($sql_stmt);
?>

(voorbeeldcode php.net)

Acties:
  • 0 Henk 'm!

  • pat42
  • Registratie: Maart 2006
  • Niet online

pat42

» lurkt

Topicstarter
@ Cartman!, CodeCaster, rest:
Normaal zou ik ook eerder voor arrays gaan, maar omdat ik alleen een (kleine) laag wil bouwen om param_bind, leek het me hier wel zo handig om het aantal/type argumenten hetzelfde te houden als bij de originele functie.

Hoewel, misschien zal ik het alsnog moeten aanpassen, want in strict mode zeurt php dat het niet mag wat ik probeer:
Declaration of mysqli_stmt_ext::bind_param() should be compatible with that of mysqli_stmt::bind_param()
Met andere woorden, ik zou de mijn eigen functie bind_param() evenveel argumenten moeten laten accepteren als de parentfunctie bind_param(), maar het aantal argumenten daarvan is dynamisch :?

Hij is overigens al gereport op php.net (ook hier).
Pagina: 1