Difference between revisions of "Retrieving request data using JInput"
From Joomla! Documentation
(Add in Joomal 3.0 and corresponding platform details)
m (→Getting Values)
|Line 33:||Line 33:|
Revision as of 00:09, 25 March 2013
To be able to use JInput as described here, you must be using Joomla 2.5.0 or above.
Please note there are known issues with JInput and Magic Quotes (Deprecated in PHP 5.3.0 and removed in PHP 5.4.0). Most servers have these turned off - however it is important to bear this in mind whilst developing a component. For this reason all core components in Joomla 2.5.x still use JRequest. As of Joomla 3.0+ magic quotes is required to be disabled and thus this is no longer an issue.
To use JInput you must first create the object by using this code:
$jinput = JFactory::getApplication()->input;
To get a value from JInput, you can use:
$foo = $jinput->get('varname', 'default_value', 'filter');
The filter defaults to
Available filters are:
Getting Multiple Values
To retrieve a number of values you can use the
$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);
$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
$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);
To set a value via JInput, you can use:
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:
<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 (  => youtube_icon.png  => Younger_Son_2.jpg ) ) [type] => Array ( [test] => Array (  => image/png  => image/jpeg ) ) [tmp_name] => Array ( [test] => Array (  => /tmp/phpXoIpSD  => /tmp/phpWDE7ye ) ) [error] => Array ( [test] => Array (  => 0  => 0 ) ) [size] => Array ( [test] => Array (  => 34409  => 99529 ) ) ) )
JInputFiles produces a result that is cleaner and easier to work with:
$files = $input->files->get('jform1');
$files then becomes:
Array ( [test] => Array (  => Array ( [name] => youtube_icon.png [type] => image/png [tmp_name] => /tmp/phpXoIpSD [error] => 0 [size] => 34409 )  => 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.
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.