How do you iterate through Input::post() data? - php

To my understanding Input::post(); with no parameters returns an array containing all the data from a specific POST..
I am doing this $all_input = Input::post();
But then I am iterating through the array Java-like (is that how you even do it?)
for ($i=0; $i<count($all_input); $i++)
{
if (strpos($all_input[$i], 'something') == true) // ERROR...
but the application crashes with error Undefined offset: 0 which I believe means that the index was not found?
I have also tried adding this to no avail:
if (!isset($all_input))
{
return;
}
If so how can you access the data to iterate through them? I know it contains data cause I can see them when I press the button during the debugging on the browser if I remove that code.
If you didn't already figure it out I am coming from Java developer and I have just started learning php so bear with me please.

According to this: https://fuelphp.com/docs/classes/input.html#/method_post Input::post(); will return $_POST which is an assoc array.
Here is the source code, because the fuelphp's documentation doesn't cover it exactly.
/**
* Fetch an item from the POST array
*
* #param string $index The index key
* #param mixed $default The default value
* #return string|array
*/
public static function post($index = null, $default = null)
{
return (func_num_args() === 0) ? $_POST : \Arr::get($_POST, $index, $default);
}
You need to refer with your input names, so if you have an input which you call 'name', in that case you need to refer $all_input['name']. You can get your keys by using array_keys() function. Also it's better if you use foreach in this situation. Like:
foreach($all_input as $key => $value) {
echo 'Input key: ' . $key . ' value: ' . $value;
}
If you left the $key => you will get only the value, you can left it, if you doesn't use it inside the foreach.
If you don't want to use foreach somewhy:
$all_input = Input::post();
$keys = array_keys($all_input);
for ($i = 0; $i < count($keys); $i++) {
if (strpos($all_input[$keys[$i]], 'something') == true) {
// Do your stuff here.
}
}
But I still recommend foreach if possible, it's less overhead and cleaner code.

This won't work because you are dealing with an Object (Input) not an array.
I recommend using a foreach loop vice a for loop. To verify the contents/structure of the Input Object you can also do a dd() to see the Input Object in its entirety.
Basically,
$input = Input::post();
foreach($input as $i) {
echo $i; //this is a property of the Input Object. if you have arrays or other objects store inside of it, you may need to go deeper into the oject either with a foreach loop again or by calling the property directly ($i->property)
};

Related

Is there way to pass Symfony variables to translation without keys

we are now using custom translations for our project in PHP and I want to migrate them to Symfony ones. Everything looks great, but my only concern is that variable placeholders needs key to bind successfully, can I somehow change the code to accept translation variables in sequence (without keys)?
Let me show an example:
Our code now:
$translator->translate('For the period %date%, %data%', [$dateInterval, $additionalData]);
But this is how Symfony wants it:
return $this->symfonyTranslator->trans('For the period %date%, %data%', ['%date%' => $dateInterval, '%data%' => $additionalData]);
This is what I want:
return $this->symfonyTranslator->trans('For the period %date%, %data%', [$dateInterval, $additionalData]);
Is this somehow possible? I didn't find it anywhere in the documentation and Google didn't help either.
I have solved it by myself this is the code (in case anyone needs it):
Basically, it gets all %variables% and sets them as array keys with corresponding array values from $parameters variable.
public function translate(string $gettextString, array $parameters = []): string
{
$gettextString = $this->newlinesNormalizer->normalize($gettextString);
preg_match_all('~\%(\S+)\%~m', $gettextString, $matches);
$variables = $matches[array_key_last($matches)];
$finalParameters = [];
foreach ($variables as $index => $variable) {
if (substr($variable, 0, 1) === '%' && substr($variable, -1) === '%') {
continue;
}
$finalParameters['%' . $variable . '%'] = $parameters[$index];
}
return $this->symfonyTranslator->trans($gettextString, $finalParameters);
}

converting a posted php array to a multidimensional array [duplicate]

So I wrote a class that can parse XML documents and create SQL queries from it to update or insert new rows depending on the settings.
Because the script has to work with any amount of nested blocks, the array that I'm putting all the values in has its path dynamically created much like the following example:
$path = array('field1','field2');
$path = "['".implode("']['",$path)."']";
eval("\$array".$path."['value'] = 'test';");
Basically $path contains an array that shows how deep in the array we currently are, if $path contains for instance the values main_table and field I want set $array['main_table']['field']['value'] to 'test'
As you can see I am currently using eval to do this, and this works fine. I am just wondering if there is a way to do this without using eval.
Something like
$array{$path}['value'] = 'test'; but then something that actually works.
Any suggestions?
EDIT
The reason I'm looking for an alternative is because I think eval is bad practice.
SECOND EDIT
Changed actual code to dummy code because it was causing a lot of misunderstandings.
Use something like this:
/**
* Sets an element of a multidimensional array from an array containing
* the keys for each dimension.
*
* #param array &$array The array to manipulate
* #param array $path An array containing keys for each dimension
* #param mixed $value The value that is assigned to the element
*/
function set_recursive(&$array, $path, $value)
{
$key = array_shift($path);
if (empty($path)) {
$array[$key] = $value;
} else {
if (!isset($array[$key]) || !is_array($array[$key])) {
$array[$key] = array();
}
set_recursive($array[$key], $path, $value);
}
}
You can bypass the whole counter business with the array append operator:
$some_array[] = 1; // pushes '1' onto the end of the array
As for the whole path business, I'm assuming that's basically an oddball representation of an xpath-like route through your xml document... any reason you can't simply use that string as an array key itself?
$this->BLOCKS['/path/to/the/node/you're/working/on][] = array('name' => $name, 'target' => $target);
You can use a foreach with variable variables.
// assuming a base called $array, and the path as in your example:
$path = array('field1','field2');
$$path = $array;
foreach ($path as $v) $$path = $$path[$v];
$$path['value'] = 'test';
Short, simple, and much better than eval.

When is it appropriate to use an ArrayObject instead of an Array

I'm wondering when, if ever it would be appropriate to use an ArrayObject() instead of an Array()? Here's an example i've been working on.
To me i'm thinking a simple array will work, but i found ArrayObject() in the manual and I'm wondering, if it would be better to use one instead of a simple array.
public function calculateTotal(){
if(count($this->items) > 0){
$n = 0;
foreach($this->items as $item){
if($item->size == 'small'){
$k = $item->price->small;
}
if($item->size == 'large'){
$k = $item->price->large;
}
$n += $k * $item->quantity;
}
}else{
$n = 0;
}
return (int) $n;
}
Now I'm confused as to how i should construct the object.
for instance can i construct it with the short array syntax?
$this->items = []; //empty object
or should i construct is as an Array object
$this->items = new ArrayObject(); //empty object
I'm also confused as to how exactly i should push new items to the array.
i have the following function i'm writing:
Also how should i append arrray objects to this object?
is this good?
public function additem($item){
$add = [
'item_id'=>$this->item_id(),
'name'=>$item['name'],
'size',$item['size'],
'quantity'=>$item['quantity'],
'price'=>[
'large'=>$item['price'],
'small'=>$item['price']
]
]
array_push($this->items,$add);
}
or should i instead use ArrayObject::append() or some other method?
I checked the manual and it says this:
public void ArrayObject::append ( mixed $value )
Appends a new value as the last element.
Note:
This method cannot be called when the ArrayObject was constructed from an object. Use ArrayObject::offsetSet() instead.
source http://php.net/manual/en/arrayobject.append.php
The reason i'm asking this now is, later on when needing to delete items from this list how will i find what i'm looking for? can i use in_array() on this object.
I apologize in advance for these questions that might seem dumb to you, but keep in mind I'm still learning some of the more technical things. Thank you
There's nothing in your first snippet that would require ArrayObject. KISS and use simple arrays: array_push($this->items,$add); or $this->items []= $add; are both fine.
As a side note, there's a discrepancy between calculateTotal and add in your code: you have to decide whether you want your item structures to be arrays ($item['price']) or objects ($item->price). My advice is to use arrays, but that's really up to you.

Filter an array in PHP

I'm trying to write a sort/filter script using an array filter function in PHP using the lambda syntax.
This achieves what I want to do, but it looks like it can be optimised:
$offersReceivedProcessedByItem = array();
foreach ($this->currentSessionUser->items as $item) {
$receivedOffersOnItem = array();
foreach ($offersReceived as $offerReceived) {
if ($offerReceived->item->id === $item->id) {
$receivedOffersOnItem[$offerReceived->id] = $offerReceived;
}
}
offersReceivedProcessedByItem[$item->id] = $receivedOffersOnItem;
}
(for each item a user has, filter through the offersReceived array and add the offer to a new array if it has an equal id, if that makes sense?!).
Here's what I'm trying:
$offersReceivedProcessedByItem = array();
foreach ($this->currentSessionUser->items as $item) {
$receivedOffersOnItem = array_filter($item->offers, function($offer){
return $offer->item->id === $item->id;
});
$offersReceivedProcessedByItem[$item->id] = $receivedOffersOnItem;
}
But i'm getting that $item is undefined, I expect it's closed scope so I tried passing $item as another argument but then i'm getting 'missing argument 2'.
I tried this using the relational approach built into Fuel but PHP eats too much memory and fails.
Any help? What am I getting wrong?
A closure doesn't know anything about the environment it is created it unless you tell it
$receivedOffersOnItem = array_filter($item->offers, function($offer) use($item){
return $offer->item->id === $item->id;
});
Notice the use-statement
A link to the manual http://php.net/functions.anonymous#example-119

Split a string to form multidimensional array keys?

I'm creating JSON encoded data from PHP arrays that can be two or three levels deep, that look something like this:
[grandParent] => Array (
[parent] => Array (
[child] => myValue
)
)
The method I have, which is simply to create the nested array manually in the code requires me to use my 'setOption' function (which handles the encoding later) by typing out some horrible nested arrays, however:
$option = setOption("grandParent",array("parent"=>array("child"=>"myValue")));
I wanted to be able to get the same result by using similar notation to javascript in this instance, because I'm going to be setting many options in many pages and the above just isn't very readable, especially when the nested arrays contain multiple keys - whereas being able to do this would make much more sense:
$option = setOption("grandParent.parent.child","myValue");
Can anyone suggest a way to be able to create the multidimensional array by splitting the string on the '.' so that I can json_encode() it into a nested object?
(the setOption function purpose is to collect all of the options together into one large, nested PHP array before encoding them all in one go later, so that's where the solution would go)
EDIT: I realise I could do this in the code:
$options['grandparent']['parent']['child'] = "myValue1";
$options['grandparent']['parent']['child2'] = "myValue2";
$options['grandparent']['parent']['child3'] = "myValue3";
Which may be simpler; but a suggestion would still rock (as i'm using it as part of a wider object, so its $obj->setOption(key,value);
This ought to populate the sub-arrays for you if they haven't already been created and set keys accordingly (codepad here):
function set_opt(&$array_ptr, $key, $value) {
$keys = explode('.', $key);
// extract the last key
$last_key = array_pop($keys);
// walk/build the array to the specified key
while ($arr_key = array_shift($keys)) {
if (!array_key_exists($arr_key, $array_ptr)) {
$array_ptr[$arr_key] = array();
}
$array_ptr = &$array_ptr[$arr_key];
}
// set the final key
$array_ptr[$last_key] = $value;
}
Call it like so:
$opt_array = array();
$key = 'grandParent.parent.child';
set_opt($opt_array, $key, 'foobar');
print_r($opt_array);
In keeping with your edits, you'll probably want to adapt this to use an array within your class...but hopefully this provides a place to start!
What about $option = setOption("grandParent", { parent:{ child:"myValue" } });?
Doing $options['grandparent']['parent']['child'] will produce an error if $options['grandparent']['parent'] was not set before.
The OO version of the accepted answer (http://codepad.org/t7KdNMwV)
$object = new myClass();
$object->setOption("mySetting.mySettingsChild.mySettingsGrandChild","foobar");
echo "<pre>".print_r($object->options,true)."</pre>";
class myClass {
function __construct() {
$this->setOption("grandparent.parent.child","someDefault");
}
function _setOption(&$array_ptr, $key, $value) {
$keys = explode('.', $key);
$last_key = array_pop($keys);
while ($arr_key = array_shift($keys)) {
if (!array_key_exists($arr_key, $array_ptr)) {
$array_ptr[$arr_key] = array();
}
$array_ptr = &$array_ptr[$arr_key];
}
$array_ptr[$last_key] = $value;
}
function setOption($key,$value) {
if (!isset($this->options)) {
$this->options = array();
}
$this->_setOption($this->options, $key, $value);
return true;
}
}
#rjz solution helped me out, tho i needed to create a array from set of keys stored in array but when it came to numerical indexes, it didnt work. For those who need to create a nested array from set of array indexes stores in array as here:
$keys = array(
'variable_data',
'0',
'var_type'
);
You'll find the solution here: Php array from set of keys

Categories