Page 1 of 1
argv[] ... multi-variable functions
Posted: Tue Jul 27, 2010 1:29 pm
by gth759k
Not sure how to state my problem; its not exactly php specific, but what I want to do is create a class function that can handle an infinite number of input variables in any non-specific order. For instance if I have one class called "Atom" that always takes in 3 parameters like ... $element = new Atom(protons, neutrons, electrons) ... in that order, how would I create a class for molecules that takes in any number of parameters like ... $substance = new Molecule($hydrogen, 2, $oxygen, 1) ... when the "Molecule" class would have no way of knowing how many parameters its going to be passed to start with? I've used argv[] before, but only with a few possible permutations of input. For those simple cases I was able to use a case/switch condition to determine what to do with each variable. I use ffmpeg via command line a lot and there are probably millions of different possible input commands, so how do large software packages like that figure out what to do with the input? Any help would be appreciated. Thanks.
Re: argv[] ... multi-variable functions
Posted: Tue Jul 27, 2010 2:35 pm
by pickle
There is also $argc I believe for the count of variables.
You haven't stated what you want to do with the parameters, or how you want to affect the behaviour of Molecule depending on the parameter count. How you figure out "what to do with the input" depends entirely on what you want Molecule to do.
Re: argv[] ... multi-variable functions
Posted: Tue Jul 27, 2010 2:55 pm
by Weirdan
$argv & $argc is for script arguments. For function/method arguments their counterparts are
func_get_args() &
func_num_args()
Re: argv[] ... multi-variable functions
Posted: Tue Jul 27, 2010 3:58 pm
by gth759k
pickle wrote:There is also $argc I believe for the count of variables.
You haven't stated what you want to do with the parameters, or how you want to affect the behaviour of Molecule depending on the parameter count. How you figure out "what to do with the input" depends entirely on what you want Molecule to do.
Don't know how I was going to use them myself. The problem is more about handling the permutations of input. For example ... I built a raytracer in php a while back and then I built a command line php script so that I could give the raytracer information without having to change any files. Here's how I handled the input.
Code: Select all
// php render.php xres 640 yres 360 camx 0 camy 0.3 camz -4
// initialize variables
switch ($argv[1]) {
case 'xres': $xres = $argv[2];
break;
case 'yres': $yres = $argv[2];
break;
case 'camx': $camx = $argv[2];
break;
case 'camy': $camy = $argv[2];
break;
case 'camz': $camz = $argv[2];
break;
}
switch ($argv[3]) {
case 'xres': $xres = $argv[4];
break;
case 'yres': $yres = $argv[4];
break;
case 'camx': $camx = $argv[4];
break;
case 'camy': $camy = $argv[4];
break;
case 'camz': $camz = $argv[4];
break;
}
switch ($argv[5]) {
case 'xres': $xres = $argv[6];
break;
case 'yres': $yres = $argv[6];
break;
case 'camx': $camx = $argv[6];
break;
case 'camy': $camy = $argv[6];
break;
case 'camz': $camz = $argv[6];
break;
}
switch ($argv[7]) {
case 'xres': $xres = $argv[8];
break;
case 'yres': $yres = $argv[8];
break;
case 'camx': $camx = $argv[8];
break;
case 'camy': $camy = $argv[8];
break;
case 'camz': $camz = $argv[8];
break;
}
switch ($argv[9]) {
case 'xres': $xres = $argv[10];
break;
case 'yres': $yres = $argv[10];
break;
case 'camx': $camx = $argv[10];
break;
case 'camy': $camy = $argv[10];
break;
case 'camz': $camz = $argv[10];
break;
}
if (is_null($xres)) {$xres = 100;}
if (is_null($yres)) {$yres = 100;}
if (is_null($camx)) {$camx = 0;}
if (is_null($camy)) {$camy = 0.3;}
if (is_null($camz)) {$camz = -4;}
printf("xres: %d\n", $xres);
printf("yres: %d\n", $yres);
printf("camx: %01.2f\n", $camx);
printf("camy: %01.2f\n", $camy);
printf("camz: %01.2f\n", $camz);
Typing into the command line ... php render.php xres 640 yres 360 camx 0 camy 0.3 camz -4 ... produces the same result as ... php render.php camx 0 xres 640 camz -4 yres 360 camy 0.3 ... so it doesn't matter what order the input is arranged. Furthermore, it doesn't need all the variables, but the problem is, as the number of input variables increases, the switch/case method doesn't scale well (the code would grow exponentially!) Does this help illustrate what I'm getting at? If my function had hundreds of input variables, then with the method above I would need thousands, maybe even millions of switch/case conditionals to handle every possible combination of input ... how do I avoid that kind of a situation?
Re: argv[] ... multi-variable functions
Posted: Tue Jul 27, 2010 4:28 pm
by pickle
You could use array_search() to see if a parameter is passed, increment the key value returned by array_search() and use that new key value to get the parameter value.
prompt> php -f myfile.php hydrogen 2 oxygen 1
Code: Select all
$hydrogen = array_search($argv,'hydrogen');
$hydrogen_count = 0;
if($hydrogen)
$hydrogen_count = $argv[$hydrogen+1];
$oxygen = array_search($argv,'oxygen');
$oxygen_count = 0;
if($oxygen)
$oxygen_count = $argv[$oxygen+1];
Re: argv[] ... multi-variable functions
Posted: Tue Jul 27, 2010 4:52 pm
by AbraCadaver
It should be easier with functions. Don't worry about the order if they are all the same (i.e. atom and number) or maybe even if they aren't the same, just use an array:
Code: Select all
function render($args) {
echo $args['xres'];
}
render(array('xres'=>640,'yres'=>360,'camx'=>0,'camy'=>0.3,'camz' -4));
For your new function, something like:
Code: Select all
class Molecule {
function __construct($args) {
foreach($args as $name => $props) {
// $name = hydrogen
// $props[0] = $hydrogen (object)
// $props[1] = 2
}
}
}
$m = new Molecule( array('hydrogen'=>array($hydrogen,2), 'oxygen'=>array($oxygen,1)) );
Or alternately with more descriptive keys:
Code: Select all
$m = new Molecule( array('hydrogen'=>array('atom'=>$hydrogen,'count'=>2), 'oxygen'=>array('atom'=>$oxygen,'count'=>1)) );
Or assuming your atom objects already contain a $name or whatever property, then just a variable number of arrays:
Code: Select all
class Molecule {
function __construct() {
foreach(func_get_args() as $args) {
// stuff
}
}
}
$m = new Molecule( array($hydrogen,2), array($oxygen,1) );
Or:
Code: Select all
$m = new Molecule( array('atom'=>$hydrogen,'count'=>2), array('atom'=>$oxygen,'count'=>1) );
Or any combination or variation, whatever makes sense to you.
Re: argv[] ... multi-variable functions
Posted: Tue Jul 27, 2010 4:59 pm
by pickle
Remember he/she's doing this from the command line, so they can't simply call:
Code: Select all
render(array('xres'=>640,'yres'=>360,'camx'=>0,'camy'=>0.3,'camz' -4));
Re: argv[] ... multi-variable functions
Posted: Tue Jul 27, 2010 5:44 pm
by gth759k
Thanks! This definitely helped.
Re: argv[] ... multi-variable functions
Posted: Tue Jul 27, 2010 6:37 pm
by AbraCadaver
pickle wrote:Remember he/she's doing this from the command line, so they can't simply call:
Code: Select all
render(array('xres'=>640,'yres'=>360,'camx'=>0,'camy'=>0.3,'camz' -4));
No, they gave the render.php command line code as an example of how they did it from the command line using $argv, but now they are writing new class methods and wondering how to do the same sort of thing. So I turned the render.php into a render() function to give an example that they could relate back to the command line way.

Re: argv[] ... multi-variable functions
Posted: Wed Jul 28, 2010 9:42 am
by pickle
How about I read the original post?
Re: argv[] ... multi-variable functions
Posted: Wed Jul 28, 2010 9:43 am
by AbraCadaver
pickle wrote:How about I read the original post?
Exactly
