Fork me on GitHub

Understanding extract($args) and pnVarCleanFromInput  Bottom

  • Developing a new module (and grateful for the Example mod as a guide), but I'm not sure I understand how the extract() function is/should be used.


    As an example, in my pnadmin.php, the "main" function displays a table containing attorney names and Edit and Delete links that call an adminapi function are formatted using pnModURL, resulting in links such as index.php?module=attorneys&type=admin&func=modify&aid=1, where aid is the attorney id. In other words, no user input is involved.


    In pnadminapi.php, after doing a security check for access, I thought it would be sufficient to only use extract($args) to obtain the 'aid' variable. Instead, the variable is not being created at all.


    If I use

    Code

    $aid = pnVarCleanFromInput('aid');
    the var is passed correctly. And, it also seems that this is an all around "safer" way of handling the data.


    So why bother with extract()?


    Just trying to come to an understanding of the best way to pass the data (and would love to know why extract() is having no effect). Thanks, in advance, for your help.
  • pnVarCleanFromInput is a custom PN function that looks at all possible ways of submitting info to the server such as cookies, POST vars, etc. extract() is a PHP function the takes an array and exports the array's values to the current symbol table. In other words, if you had an array like myArray('value1'->1,'value2'->2) and you did an extract() on it, you would then have two stand alone variables like $value1 = 1 and $value2 = 2.

    Basically, they are for totally different purposes. In adminapi.php, you're getting vars that are already in the PHP script but were passed to the API function as an argument. If you were in the admin.php page, you would probably us pnVarCleanFromInput to get vars from the remote client (a form input for example).
  • Quote

    So why bother with extract()?

    1 simple answer: don't bother; it causes more trouble that it's worth.

    The reason is simple: extract() takes your array and imports it into your current namespace (ie: it creates variables from you associative array indexes). The problem with this is that all of a sudden you have variables defined which can not be traced back to any declarative statement which means that at this point you can't tell from your code where a variable comes from (and whether it's a variable which really ought to be there or whether it's a typo).

    When dealing with arrays containing arguments, use the following construct:

    Code

    $mykey = $myarray['mykey']

    It's a bit more code but it clearly spells out where $mykey comes from which IMHO greatly enhances maintainability in the long term.

    Greetings
    R
  • The purpose of bringing in arguments that are passed to the function in addition to those passed via the URL is so that all PN functions can be called in a scripted fashion and not just through the web interface. For example I can write a custom PHP script run from the command line that might call parts of your module.

    Another use of this functionality is the start page settings in .76x+ where you can set the default arguments for the start page. If you module doesn't utilise arguments passed to it then this functionality will be limited to just selecting your module as the start page.

    -Mark

    --
    Visit My homepage and Zikula themes.
  • Thanks for the responses guys.

    Quote

    The purpose of bringing in arguments that are passed to the function in addition to those passed via the URL is so that all PN functions can be called in a scripted fashion and not just through the web interface.


    Mark,
    Do I understand your comment to state that for purposes of greater flexibility (other developers being able to call and use my mod's functions), I should continue to include the extract($args) line in API functions (in addition to using pnVarCleanFromInput for those vars that are passed in the URL)?

    Pretty sure I'm understanding this more clearly now -- appreciate the feedback. icon_smile
  • Yes and no... You should continue to support arguments passed in as parameters to the function. However i'd recommend not using extract (we're removing it's usage from the core and associated modules...). This is because every single parameter passed into the function ends up as a variablle in the scope of your function with possibly unexpected results.

    Rather than extract the args array just check for $args['your var'] and set this if required.

    e.g.

    Code

    $myvar = pnVarCleanFromInput('myvar');
    if (isset($args['myvar'])) {
        $myvar = $args['myvar'];
    }


    We make the process a lot simpler in .8x with the object library where you can use

    Code

    $myvar = FormUtil::getPassedValue('myvar', isset($args['myvar']) ? $args['myvar'] : yourdefault);


    -Mark

    --
    Visit My homepage and Zikula themes.
  • Just a quick question, can you pass the $arg back in through pnModUrl

    ie

    return pnRedirect(pnModURL('Example', 'user', 'new', $args));

    What Im' trying to do is validate form input if it fails, display the error message and reload the same values in the form and let them continue.

    I have about 15 vars so instead of typing them all out in an assignment array, can above be done? DOesn't seem to be working for me.
  • You should really take a look at pnForms in .8 - That does all the validating, passing back and forth in a few lines of code. So if don't really depend on .7 compatibility you should switch. icon_wink

    --
    best regards from Kiel, sailing city

    Steffen Voss

    Member of the Zikula Steering Committee
    Read The Zikulan's Blog "If you want people to RTFM, make a better FM!"
  • Ok, I will have to check that out ASAP. However for .7xx am I correct in assuming above would not work ?

This list is based on users active over the last 60 minutes.