Difference between revisions of "Retrieving request data using JInput"

From Joomla! Documentation

(Add superglobals)
m (Update version number)
(10 intermediate revisions by 4 users not shown)
Line 1: Line 1:
{{JVer|11.1}} {{JVer|1.7}}
+
{{JVer|11.1}} {{JVer|2.5}}
  
 
==Requirements==
 
==Requirements==
To be able to use JInput as described here, you must be using Joomla 1.7.1 or above.
+
To be able to use JInput as described here, you must be using Joomla 2.5.0 or above.
  
==Starting JInput==
+
==Using JInput==
 
To use JInput you must first create the object by using this code:
 
To use JInput you must first create the object by using this code:
  
 
<source lang="php">$jinput = JFactory::getApplication()->input;</source>
 
<source lang="php">$jinput = JFactory::getApplication()->input;</source>
  
===Getting values===
+
===Getting Values===
To get a value from JInput you can use:
+
To get a value from JInput, you can use:
  
 
<source lang="php">$foo = $jinput->get('varname', 'default_value', 'filter');</source>
 
<source lang="php">$foo = $jinput->get('varname', 'default_value', 'filter');</source>
  
The filter defaults to cmd
+
The filter defaults to <code>cmd</code>.
  
 
Available filters are:
 
Available filters are:
Line 35: Line 35:
 
*USERNAME
 
*USERNAME
  
To retrieve a number of values you can use the getArray() method like:
+
===Getting Multiple Values===
 +
 
 +
To retrieve a number of values you can use the <code>getArray()</code> method:
  
 
<source lang="php">
 
<source lang="php">
$fooarray = array();
+
$fooValues = $jinput->getArray(array('var1' => '', 'var2' => '', 'var3' => ''));
$fooarray[] = 'var1';
+
</source>
$fooarray[] = 'var2';
 
$fooarray[] = 'var3';
 
$foovalues = $jinput->getArray($fooarray);</source>
 
  
The $foovalues will be an array that consists of the same keys as used in $fooarray.
+
or, if you want to determine the data to get step by step:
 +
 
 +
<source lang="php">
 +
$fooArray = array();
 +
$fooArray['var1'] = '';
 +
$fooArray['var2'] = '';
 +
$fooArray['var3'] = '';
 +
$fooValues = $jinput->getArray($fooArray);
 +
</source>
 +
 
 +
The <code>$fooValues</code> will be an array that consists of the same keys as used in <code>$fooArray</code>, but with values attached.
 +
 
 +
You can also specify different filters for each of the inputs:
 +
 
 +
<source lang="php>
 +
$fooValues = $jinput->getArray(array(
 +
    'var1' => 'int',
 +
    'var2' => 'float',
 +
    'var3' => 'word'
 +
));
 +
</source>
 +
 
 +
You can also nest arrays to get more complicated hierarchies of values:
 +
 
 +
<source lang="php">
 +
$fooValues = $jinput->getArray(array(
 +
    'jform' => array(
 +
        'title' => 'string',
 +
        'quantity' => 'int',
 +
        'state' => 'int'
 +
    )
 +
));
 +
</source>
  
To retrieve values from a specific super global you can use:
+
===Getting Values from a Specific Super Global===
  
 
<source lang="php">$foo = $jinput->get->get('varname', 'default_value', 'filter');</source>
 
<source lang="php">$foo = $jinput->get->get('varname', 'default_value', 'filter');</source>
Line 52: Line 83:
 
<source lang="php">$foo = $jinput->server->get('varname', 'default_value', 'filter');</source>
 
<source lang="php">$foo = $jinput->server->get('varname', 'default_value', 'filter');</source>
  
===Setting values===
+
To retrieve an entire object, you can use:
To set a value via JInput you can use:
+
<source lang="php">$foo = $jinput->get('varname', null, null);</source>
 +
 
 +
===Setting Values===
 +
 
 +
To set a value via JInput, you can use:
  
 
<source lang="php">$jinput->set('varname', $foo);</source>
 
<source lang="php">$jinput->set('varname', $foo);</source>
  
 +
===Retrieving File Data===
 +
 +
The format that PHP returns file data in for arrays can at times be awkward, especially when dealing with arrays of files. JInputFiles provides a convenient interface for making life a little easier, grouping the data by file.
 +
 +
Suppose you have a form like:
 +
<source lang="html4strict">
 +
<form action="<?php echo JRoute::_('index.php?option=com_example&task=file.submit'); ?>" enctype="multipart/form-data" method="post">
 +
<input type="file" name="jform1[test][]" />
 +
<input type="file" name="jform1[test][]" />
 +
<input type="submit" value="submit" />
 +
</form>
 +
</source>
 +
 +
Normally, PHP would put these in an array called <code>$_FILES</code> that looked like:
 +
<pre>
 +
Array
 +
(
 +
    [jform1] => Array
 +
        (
 +
            [name] => Array
 +
                (
 +
                    [test] => Array
 +
                        (
 +
                            [0] => youtube_icon.png
 +
                            [1] => Younger_Son_2.jpg
 +
                        )
 +
 +
                )
 +
 +
            [type] => Array
 +
                (
 +
                    [test] => Array
 +
                        (
 +
                            [0] => image/png
 +
                            [1] => image/jpeg
 +
                        )
 +
 +
                )
 +
 +
            [tmp_name] => Array
 +
                (
 +
                    [test] => Array
 +
                        (
 +
                            [0] => /tmp/phpXoIpSD
 +
                            [1] => /tmp/phpWDE7ye
 +
                        )
 +
 +
                )
 +
 +
            [error] => Array
 +
                (
 +
                    [test] => Array
 +
                        (
 +
                            [0] => 0
 +
                            [1] => 0
 +
                        )
 +
 +
                )
 +
 +
            [size] => Array
 +
                (
 +
                    [test] => Array
 +
                        (
 +
                            [0] => 34409
 +
                            [1] => 99529
 +
                        )
 +
 +
                )
 +
 +
        )
 +
 +
)
 +
</pre>
 +
 +
JInputFiles produces a result that is cleaner and easier to work with:
 +
<source lang="php">
 +
$files = $input->files->get('jform1');
 +
</source>
 +
 +
<code>$files</code> then becomes:
 +
 +
<pre>
 +
Array
 +
(
 +
    [test] => Array
 +
        (
 +
            [0] => Array
 +
                (
 +
                    [name] => youtube_icon.png
 +
                    [type] => image/png
 +
                    [tmp_name] => /tmp/phpXoIpSD
 +
                    [error] => 0
 +
                    [size] => 34409
 +
                )
 +
 +
            [1] => Array
 +
                (
 +
                    [name] => Younger_Son_2.jpg
 +
                    [type] => image/jpeg
 +
                    [tmp_name] => /tmp/phpWDE7ye
 +
                    [error] => 0
 +
                    [size] => 99529
 +
                )
 +
 +
        )
 +
 +
)
 +
</pre>
 +
 +
In this way, the data from each file element is consolidated into a single array and can be indexed in a more straightforward manner.
 +
 +
== Background ==
  
 
This is based on an email discussion: [https://groups.google.com/d/msg/joomla-dev-framework/LbALkK1ifMo/5waSiIlb21gJ Framework List 23 July 2011]
 
This is based on an email discussion: [https://groups.google.com/d/msg/joomla-dev-framework/LbALkK1ifMo/5waSiIlb21gJ Framework List 23 July 2011]
Line 80: Line 227:
  
 
We'll be adding input as a public property to JApplication in the near future.  It might be an idea if the CMS folks so chose to release a 1.7.1 that included this so developers can use it now.  Otherwise, at this point in time, it is best to still use JRequest.
 
We'll be adding input as a public property to JApplication in the near future.  It might be an idea if the CMS folks so chose to release a 1.7.1 that included this so developers can use it now.  Otherwise, at this point in time, it is best to still use JRequest.
 +
 +
[[Category:Development]]

Revision as of 13:57, 16 August 2012

Joomla 11.1 Joomla 2.5

Requirements[edit]

To be able to use JInput as described here, you must be using Joomla 2.5.0 or above.

Using JInput[edit]

To use JInput you must first create the object by using this code:

$jinput = JFactory::getApplication()->input;

Getting Values[edit]

To get a value from JInput, you can use:

$foo = $jinput->get('varname', 'default_value', 'filter');

The filter defaults to cmd.

Available filters are:

  • INT
  • INTEGER
  • UINT
  • FLOAT
  • DOUBLE
  • BOOL
  • BOOLEAN
  • WORD
  • ALNUM
  • CMD
  • BASE64
  • STRING
  • HTML
  • ARRAY
  • PATH
  • USERNAME

Getting Multiple Values[edit]

To retrieve a number of values you can use the getArray() method:

$fooValues = $jinput->getArray(array('var1' => '', 'var2' => '', 'var3' => ''));

or, if you want to determine the data to get step by step:

$fooArray = array();
$fooArray['var1'] = '';
$fooArray['var2'] = '';
$fooArray['var3'] = '';
$fooValues = $jinput->getArray($fooArray);

The $fooValues will be an array that consists of the same keys as used in $fooArray, but with values attached.

You can also specify different filters for each of the inputs:

$fooValues = $jinput->getArray(array(
    'var1' => 'int',
    'var2' => 'float',
    'var3' => 'word'
));

You can also nest arrays to get more complicated hierarchies of values:

$fooValues = $jinput->getArray(array(
    'jform' => array(
        'title' => 'string',
        'quantity' => 'int',
        'state' => 'int'
    )
));

Getting Values from a Specific Super Global[edit]

$foo = $jinput->get->get('varname', 'default_value', 'filter');
$foo = $jinput->post->get('varname', 'default_value', 'filter');
$foo = $jinput->server->get('varname', 'default_value', 'filter');

To retrieve an entire object, you can use:

$foo = $jinput->get('varname', null, null);

Setting Values[edit]

To set a value via JInput, you can use:

$jinput->set('varname', $foo);

Retrieving File Data[edit]

The format that PHP returns file data in for arrays can at times be awkward, especially when dealing with arrays of files. JInputFiles provides a convenient interface for making life a little easier, grouping the data by file.

Suppose you have a form like:

<form action="<?php echo JRoute::_('index.php?option=com_example&task=file.submit'); ?>" enctype="multipart/form-data" method="post">
	<input type="file" name="jform1[test][]" />
	<input type="file" name="jform1[test][]" />
	<input type="submit" value="submit" />
</form>

Normally, PHP would put these in an array called $_FILES that looked like:

Array
(
    [jform1] => Array
        (
            [name] => Array
                (
                    [test] => Array
                        (
                            [0] => youtube_icon.png
                            [1] => Younger_Son_2.jpg
                        )

                )

            [type] => Array
                (
                    [test] => Array
                        (
                            [0] => image/png
                            [1] => image/jpeg
                        )

                )

            [tmp_name] => Array
                (
                    [test] => Array
                        (
                            [0] => /tmp/phpXoIpSD
                            [1] => /tmp/phpWDE7ye
                        )

                )

            [error] => Array
                (
                    [test] => Array
                        (
                            [0] => 0
                            [1] => 0
                        )

                )

            [size] => Array
                (
                    [test] => Array
                        (
                            [0] => 34409
                            [1] => 99529
                        )

                )

        )

)

JInputFiles produces a result that is cleaner and easier to work with:

$files = $input->files->get('jform1');

$files then becomes:

Array
(
    [test] => Array
        (
            [0] => Array
                (
                    [name] => youtube_icon.png
                    [type] => image/png
                    [tmp_name] => /tmp/phpXoIpSD
                    [error] => 0
                    [size] => 34409
                )

            [1] => Array
                (
                    [name] => Younger_Son_2.jpg
                    [type] => image/jpeg
                    [tmp_name] => /tmp/phpWDE7ye
                    [error] => 0
                    [size] => 99529
                )

        )

)

In this way, the data from each file element is consolidated into a single array and can be indexed in a more straightforward manner.

Background[edit]

This is based on an email discussion: Framework List 23 July 2011

The idea behind JInput is to abstract out the input source to allow code to be reused in different applications and in different contexts. What I mean by this is that you could have a controller that grabs data from an input source. Instead of always getting it from the request (i.e. get and post variables), you get it from JInput. So say for instance you have a MVC triad in your component that is meant to get data from the browser as a client (a typical web application). Now suppose you want to reuse that same code but interface with it using JSON. Instead of rewriting your triad, you just extend JInput and have it grab it data from a parsed json object and perform any translation that you need to perform.

The plan is to have JApplication instantiate JInput in its constructor. Then in your code you get the input object from the application and get your input from there. It will be a public property in Japplication so that it can be swapped out of that is appropriate.

We get the added benefit that we get rid of the static JRequest which makes a whole bunch the code a whole lot easier to test because you can inject mock inputs directly instead of trying to fudge with hackish dependencies.

The end result will be that your code will get the input object from the application (we will probably add something to JController at some point to make it more convenient to use there as well).

Once you have your JInput object, you use it fairly in a fairly similar manner to how JRequest is used: $input->get('varname', 'default_value', 'filter');

Where filter is a filter that is supported by JFilterInput. JInput::clean proxies to JFilter. We'll have to tweak JFilter a little bit so that it is more extensible. It defaults to cmd so that developers have to be intentional about things if they want to have more lenient filtering.

There is also a getArray method that allows you to specify an array of key and filter pairs so that you can get a whole array of filtered input.

If you want to get data from a specific super global array, you can do $input->get->get(...) or $input->post->get(...).

So that's the basic idea. Feel free to post more questions if you have any.

We'll be adding input as a public property to JApplication in the near future. It might be an idea if the CMS folks so chose to release a 1.7.1 that included this so developers can use it now. Otherwise, at this point in time, it is best to still use JRequest.