Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 7 of 7
  1. #1
    Regular Coder
    Join Date
    Mar 2003
    Posts
    176
    Thanks
    0
    Thanked 0 Times in 0 Posts

    Passing Variable Number of Arguments

    Hi all,
    Im trying to construct a generic php class to handle form validation, particularly for logins. I have written a method - getFormData() - that accepts as arguments, the associative-array-value(s) of the form element name(s). It also accepts any number of arguments.

    The html form is set up like so:
    Code:
    <form action="foo.php">
    <input type="text" name="user[Username]" />
    <input type="password" name="user[Password]" />
    <input type="password" name="user[Confirm Password]" />
    <input type="text" name="user[Email Address]" />
    <input type="submit" value="Submit" />
    </form>
    I can pass the array value to the getFormData() method as an argument and it returns the name-value pair for the form. Here is the getFormData() method:
    Code:
    //foo.php
    function getFormData()
    {
      $arg_list = func_get_args();
      $cnt = count($_POST[user]);
      $fld_name = array_keys($_POST[user]);
      $fld_value = array_values($_POST[user]);
      $i = 0;
      
      while($i < $cnt)
      {
          if($fld_name[$i] == $arg_list[$i])
          {
              $stack[$fld_name[$i]] =  $fld_value[$i];
          }
          $i++;
      }
       return $stack;
    }
    
    //this is how im currently calling the function; 
    $keys = array_keys(getFormData('Username','Password'));
    $vals = array_values(getFormData('Username','Password'));
    $c = count(getFormData('Username','Password'));
    $j=0;
    
      while($j<$c)
      {
          print 'Key: '.$keys[$j].'  Value:  '.$vals[$j].' <br>';
          $j++;
      }
    What I would like to do is to have a series of validation methods that accept as arguments any form element name (thats in the user[] array), have any validation method access the getFormData() method and return the appropriate values. After that I can do whatever validation is necessary. For example:
    Code:
    function foodleBot($args)
    {
      //get arguments passed to foodleBot;
      //pass all $args to getFormData();
      //get the return values and validate;
    }
    
    //example calls
    //foodleBot('Password','Confirm Password');
    //foodleBot('Username','Password','Email');
    However, I'm having trouble extracting the arguments from the validation function and passing them to getFormData(). In fact, I've confused myself trying different things. For example, this wont work - even if I change the getFormData() return type to an array: ie return array($stack); -
    Code:
    function foodleBot($flds)
    {
    $args = func_get_args();
    $keys = array_keys(getFormData($args));
    $vals = array_values(getFormData($args));
    $c = count(getFormData($args));
    //$c=func_num_args();
    $j=0;
    
      while($j<$c)
      {
          print 'Key: '.$keys[$j].'  Value:  '.$vals[$j].' <br>';
          $j++;
      }
    }
    
    //example call
    foodleBot('Password','Confirm Password');
    I forget which, but I think it returns null. It does work if I call it outside a function as per the getFormData() code (way) above. That ways no good because the argument values have to be hardwired.

    Any help would be appreciated.

    HT
    Last edited by HairyTeeth; 10-27-2003 at 05:38 AM.

  • #2
    Senior Coder
    Join Date
    Jun 2002
    Location
    frankfurt, german banana republic
    Posts
    1,848
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Your problem is that your getFormData() function does expect a variable number of arguments, which must all be strings, but in foodleBot() you're passing an array instead. Here's a fixed version of it and some minor readability enhancements too:

    PHP Code:
    function getFormData() {
        
    $args func_get_args();
        
        
    //    is an array passed instead?
        
    if (count($args) == && is_array($args[0])) {
            
    $args $args[0];
        }
            
        
    $matches = array();
        foreach (
    $_POST['user'] as $key => $value) {
            if (
    in_array($key$args)) {
                 
    $matches[$key] = $value;    
            }        
        }
        return 
    $matches;

    P.S: Two nitpickings: Don't call a variable "stack" if you don't use it as one. And don't shorten names like "field" to "fld" and "count" to "cnt" by stripping the vocals - the extra characters typed pay off through enhanced readability and don't really slow the parser down. But that's just me and my standards...
    De gustibus non est disputandum.

  • #3
    Regular Coder
    Join Date
    Mar 2003
    Posts
    176
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Mordred, now that is a nice function! Not just because it works so wonderfully , but because of it's brevity. I can now rewrite foodleBot() like this:
    PHP Code:
    function foodleBot()
    {
        
    $args func_get_args();
        
    $item getFormData($args);

        foreach(
    $item as $keys=>$value)
        {
            print 
    'Key: '.$keys.'  Value:  '.$value.' <br>';
        }

    ... which is far, far better than how I had been approaching it before (I had used the foreach construct in other incarnations of foodleBot() but those functions never turned out as neat as this one).
    Between making this post and reading your reply, I had discovered that the problem lay somewhere with the the variable datatype but I was still a long way off from a solution like yours.

    Regarding your nitpickings ..
    I used $stack because this line:

    $stack[$fld_name[$i]] = $fld_value[$i];

    has the same effect as array_push(), which treats arrays as a stack - but you are right, it isn't a stack at all.

    I agree with the points you make about variable names and readability. PHP has coding conventions that I must learn (not that I've seen $fld as a coding convention anywhere! )

    Thanks for your help and constructive critisims Mordred!

    Cheers.

  • #4
    Senior Coder
    Join Date
    Jun 2002
    Location
    frankfurt, german banana republic
    Posts
    1,848
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Regarding the standard PHP coding conventions, many people adhere (more or less) to those used for the PEAR project:
    http://pear.php.net/manual/en/standards.php

    About the style of variable/method/class naming, I found this link quite helpful and inspiring:
    http://www.objectmentor.com/resource...#Pronounceable
    De gustibus non est disputandum.

  • #5
    Regular Coder
    Join Date
    Mar 2003
    Posts
    176
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Thanks for the links Mordred - bookmarked for later digestion.

    I would just like to confirm my understanding of the code snippet below and ask a couple of questions along the way:

    This snippet:
    PHP Code:
    $args func_get_args();
    if (
    count($args) == && is_array($args[0])) {
        
    $args $args[0];

    If either (a) an array is passed as an argument to getFormData() or (b) a single non-array argument such as 'Username' is passed as an argument to getFormData(), then count($args) will = 1.

    If an array is passed then the value of $args[0] will be of type Array (gettype() = array) and is_array($args[0]) will be true (as will the whole condition).

    Otoh, if a single string argument is passed, the value of $args[0] will be the value of that argument; the type will not be Array (eg. gettype() = string) and the is_array() test will return false.

    $args = $args[0] formally implements (redeclares?, casts?, reassigns?) the $args variable as an array() with key=>value pairs. Is it that the func_get_args() implements arrays differently to array(), say, as a list?

    As for the rest, I'm happy with my understanding. The in_array() function certainly saves a few lines of code.

    Thanks for youre time Mordred.

    HT

  • #6
    Senior Coder
    Join Date
    Jun 2002
    Location
    frankfurt, german banana republic
    Posts
    1,848
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Originally posted by HairyTeeth
    If either (a) an array is passed as an argument to getFormData() or (b) a single non-array argument such as 'Username' is passed as an argument to getFormData(), then count($args) will = 1.
    Not quite: count($args) just gives you the number of argumetns passed to the function. But I think you meant that in your (a) part. It is the first part of a barrier that checks if the only argument passed is an array.

    If an array is passed then the value of $args[0] will be of type Array (gettype() = array) and is_array($args[0]) will be true (as will the whole condition).
    Yes, that's correct.

    Otoh, if a single string argument is passed, the value of $args[0] will be the value of that argument; the type will not be Array (eg. gettype() = string) and the is_array() test will return false.
    Yes, and that makes the whole AND-condition return false, thus neglecting the next part.

    $args = $args[0] formally implements (redeclares?, casts?, reassigns?) the $args variable as an array() with key=>value pairs. Is it that the func_get_args() implements arrays differently to array(), say, as a list?
    I'd say the more correct term would be: $args = $args[0] means that the value of $args[0] will be assigned to $args. By doing this, we overwrite the former value stored in $args. I guess you could also call that a "reassignment" of $args.

    It's definitely not a cast, a cast is always an explicit type coercion, like $args = (int) $foo. The "(int)" is a cast operator.

    The type of array is not really a key-value pair array, but OTOH it is. Sounds confusing? That's due to PHPs arrays, they always have keys and values. But generally one thinks of key-value arrays (or associative arrays) as arrays with string keys, as opposed to numerically indexed arrays.

    But we don't enforce a certain kind of array through this assignment. We just suppose it's a list with numerical indices, but it is not guaranteed it is. Anyway, later down with in_array(), only the values are what interests us, so we don't get concerned what keys this array might or might not have.

    As for the rest, I'm happy with my understanding. The in_array() function certainly saves a few lines of code.
    I can only recommend experimenting with the big array function library that ships with PHP. There are some real goodies in there, such as array_map(), array_filter() and array_walk(). If you learn to use them, you can save yourself a lot of for-loop writing in the future... and believe me, writing for loops is not very... eh... elegant. The "advanced" array features provide some kind of beauty through simplicity, if you understand what I mean here. Ok, I stop with this esoteric rambling. For now.
    De gustibus non est disputandum.

  • #7
    Regular Coder
    Join Date
    Mar 2003
    Posts
    176
    Thanks
    0
    Thanked 0 Times in 0 Posts
    Originally posted by mordred
    The type of array is not really a key-value pair array, but OTOH it is. Sounds confusing? That's due to PHPs arrays, they always have keys and values. But generally one thinks of key-value arrays (or associative arrays) as arrays with string keys, as opposed to numerically indexed arrays.
    Would it be right to think of it in terms of sequential arrays and associative arrays? The way func_get_args() interprets the agruments was confusing..."an array is not necessarily an array" it seems.

    The "advanced" array features provide some kind of beauty through simplicity, if you understand what I mean here. Ok, I stop with this esoteric rambling. For now.
    lol, no rambling, you just gave me a 101 on "good coding practice". Theres a subtlety in good code - it takes advantages of things. To me, this is good code, and yes, it's damn beautiful to read.

    Callback functions!!! Wow...i like!


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •