Im having a little trouble in referencing indexes in arrays in Smarty. I believe that it is because the variable I am using as the index is a string. How may I cast this string as a integer within the template?
Thanks.
If I correctly understand the question, {$variable|intval}
The documentation shows many usage examples, especially with regards to accessing array elements.
{$foo} <-- displaying a simple variable (non array/object)
{$foo[4]} <-- display the 5th element of a zero-indexed array
{$foo.bar} <-- display the "bar" key value of an array, similar to PHP $foo['bar']
{$foo.$bar} <-- display variable key value of an array, similar to PHP $foo[$bar]
{$foo[bar]} <-- syntax only valid in a section loop, see {section}
I believe that it is because the
variable I am using as the index is a
string
I don't agree with that belief:
$arr = array('a');
$i = '0';
echo $arr[$i]; // echos a
I think the problem lies elsewhere. If you have further questions, you should include some of your code.
If it's already assigned to a variable, say $var, you can set the type of a variable like this:
{$converted = settype ($var, 'integer')}
You don't have to use the $converted value, but if you don't assign it, the bool will show up in your page.
since i am not allowed to comment (doh), i will just say that #webbiedave code is correct in php, but in smarty it doesnt work. i have just spent too much time trying to figure it out why i am not accessing data from array in template, and i found out that i had array with integer keys and the parameter which i used for key in smarty was string, so it wasnt working as expected. i solved it like that:
<!--{debug says}
{$item}=> Array (2)
name=> "lalala"
id => "123"
...
{$arrays} => Array (7)
123=> Array (3)
other_part_i_care=> "bebebe"
...
-->
{$arrays[$item.id].other_part_i_care} <!--this doesnt return anything-->
{assign var='item_id' value=$item.id} <!--my guess here it gets interpreted as int -->
{$arrays[$item_id].other_part_i_care} <!--this return expected outcome-->
Related
If you are a PHP developer you most probably have seen the following notice:
Notice: Only variables should be passed by reference in /somefile.php
on line xxx
(Problem extensivley treated in Only variables should be passed by reference)
Example throwing notice:
$string = "hi-dude";
echo end(explode('-', $string));
Working example:
$string = "hi-dude";
$strings = explode('-', $string);
echo end($strings);
Explanation:
Only real variables may be passed by reference, not functions which are returning the correct variable.
However I can not think of a good reason why this notice is happening. It feels unecessary and requires me to write a lot of extra lines of code sometimes. What is the reason for PHP having this strange restriction? Why does this problem even exist?
end() or array_pop() will return the E_NOTICE with message
Only variables should be passed by reference
The reason is that end() requires a reference, because it makes the current element pointer point to the last element.
You can do it with one line,
$string = "this-is-a-sample-text";
echo substr(strrchr($string, '-'), 1);
DEMO: https://3v4l.org/jO29n
Finally I found a great explanation which helped me to understand this: What's the difference between passing by reference vs. passing by value?
As Daniel Pryden states:
In simplest terms:
call by value means that you pass values as function arguments
call by reference means that you pass variables as function arguments
In metaphoric terms:
Call by value is where I write down something on a piece of paper and hand it to you. Maybe it's a URL, maybe it's a complete copy of
War and Peace. No matter what it is, it's on a piece of paper which
I've given to you, and so now it is effectively your piece of paper.
You are now free to scribble on that piece of paper, or use that piece
of paper to find something somewhere else and fiddle with it,
whatever.
Call by reference is when I give you my notebook which has something written down in it. You may scribble in my notebook (maybe I
want you to, maybe I don't), and afterwards I keep my notebook, with
whatever scribbles you've put there. Also, if what either you or I
wrote there is information about how to find something somewhere else,
either you or I can go there and fiddle with that information.
In this case the notice "Only variables should be passed by reference" is still unjustified as we are only interested in retrieving the last value of the array. However the function end() is defined like
mixed end ( array &$array )
The & sign which states passing by reference is there for a certain reason: end() is not just returning the last element of an array, it also changes its internal pointer to the end. Therefore the array is modified.
If we only would return the last element of an array without touching the array there would be no need to pass the array by reference and we would not get this notice. But end() is somehow the wrong function for that.
What if there is no justification for me getting this notice?
Note that also the function to be called might be defined wrong. In my case I hade a function defined like this:
/**
* Flatten an array by one level if only needing a certain key value from a sub array.
*
* Example: [["foo"=>"bar","foo"=>"cheese"]]
* Result: ["bar","cheese"]
*
* #param $array: The input array.
* #param $key: The key to flatupshift. Default is 0.
* #return $array: The result
*/
private function array_flatupshift(&$array, $key = 0) {
$a = [];
foreach ($array as $item) {
if (is_object($item)) {
array_push($a, $item->$key);
} else if (is_array($item)) {
array_push($a, $item[$key]);
}
}
return $a;
}
This is simply a wrong function definition. So if you also get notices like this: Check if the function you call is defined correctly. Passing by reference does not make sense here as the array being passed is not touched in any way. Therefore the function definition should be without the "reference &/":
private function array_flatupshift($array, $key = 0) {
There are some cases where you MIGHT use the error control operator if you know what you are doing. Therefore:
$string = "hi-dude";
echo #end(explode('-', $string));
... would be o.k. I guess is the result of explode is not needed anymore. However notice the drawbacks of suppressing all possible errors. Please correct me if I go wrong here.
I have created array variable in .php file
like
$arImagePath[TE] = 'XYZ';
in my .tpl
{$carnumber} is giving 'T' and {$carinitial} is giving 'E'.
I am trying to get value 'XYZ' as follows
{$arImagePath[{$carnumber}+{$carinitial}]}
I tried many combination still unavailable to get array value.
smarty version -2.6.26
Hoping for any help.
From documentation (Smarty v2) :
{$foo[bar]} <-- syntax only valid in a section loop, see {section}
So, if you want to access the array variable directly and you are not in a loop, you have to do it this way:
{$foo.bar} <-- display the "bar" key value of an array, similar to
PHP $foo['bar']
Now, to archive what you need:
// This assignment could change dynamically
{assing var="carnumber" value="T"}
{assing var="carinitial" value="E"}
// For the sake of clarity, I'm going to concat in one variable the above assignments
{assing var="index" value=$carnumber|cat:$carinitial}
//Now access the array at the index we need
{$arImagePath.$index} // XYZ
In my code, I fill an array using this line in a loop :
$_SESSION['my_array'][] = $some_value;
After each execution of this line, I do some check (doesn't matter here for which purpose) using the function in_array(). However, at the first iteration it says :
« in_array() expects parameter 2 to be array ».
How to fix this problem?
You can initialize the array (before you fill it with values) like this:
$_SESSION['my_array']=array();
This way you can be sure that it is array, even when it would be empty.
You are assigning or accesing it wrongly
Use this
$_SESSION['my_array'] = $some_value;
When you are doing the in_array check, you can cast the second item to an array, so if it's empty then it will pass an empty array. This way you don't ever set anything to the session when you don't need to (which could trip you up later on)
e.g.,
if (in_array('foo', (array)$_SESSION['my_array'])) {
// do something
}
I feel stupid for asking this cause it seems so basic but it's really bugging me.
I have a method that returns an array with a single element. I just want it to return the element not wrapped in an array. I tried this.
return $f->getValue()[0];
and it gives an error but if I save it to a variable, it works fine.
$v = $f->getValue();
return $v[0];
I can't figure it out....
It's available only since PHP 5.4: http://codepad.viper-7.com/VHOW0o
What you are trying to do, is called array dereferencing, and is only possible in PHP as of version 5.4 (if you scroll up a few lines in the documentation article I linked to, you'll see it mentioned).
Use reset().
<?php return reset( $f->getValue() ); ?>
Edit: reset() is probably superior to current() as it also makes sure that the internal pointer is reset, despite it not making much difference if the array only contains one element.
As far as I know since you are returning an array you only can get an array. You can instead save the array to a variable in the class (accessible by $f->myArray) and then return just the string portion. Or the other option is to do what your second example is and return the array and retrieve the string from it.
have you tried this
<?php
return array_shift(array_values($array));
?>
Get the first element of an array
I have variable that in PHP controller looks like
$data['content']['mods']['HTML-FORM-END']['html']
It is passed nicely in smarty, but when I try to show it any of these ways, it shows either 0 (assumes minus as operator and does some math), or says "unrecognized tag"
{$data.content.mods.HTML-FORM-BEGIN.html}
{$data.content.mods['HTML-FORM-BEGIN']['html']}
{$data.content.mods.HTML-FORM-BEGIN.html}
{$data.content.mods.HTML-FORM-BEGIN.html}
How can i print it without renaming array key in controller?
Your example references 'HTML-FORM-END' in your controller but 'HTML-FORM-BEGIN' in your view but I'll assume that isn't your issue and both exist. How about this?
{$data[content][mods][HTML-FORM-BEGIN][html]}
From what I can find it appears that the only way to get down into a multi-dimensional array in Smarty is with loops. Perhaps instead you could split your array into assigns in your controller to provide easy access:
foreach($data['content']['mods'] as $key => $values) {
$smarty->assign('content_mods_' . $key, $values['html'];
}
and then you could reference them in your template like this:
{$content_mods_HTML-FORM-BEGIN}
{$content_mods_HTML-FORM-END}
// etc.