Using of PHP constants in foreach loop - php

I need to use PHP contants in foreach loop:
define('WEBS', 'http://google.com, http://yahoo.com');
foreach (WEBS as $a) {
//do something
}
However I managed to do that by following code, although it works fine but aptana editor shows syntax error. Please guide me how to do that in the correct manner.
foreach (get_defined_constants(true)['user']['WEBS'] as $w) {
//do something
}

You have to explode the values first
foreach (explode(', ', WEBS) as $url) { ...
explode() will break a string into an array so that you can iterate through it
Alternatively, you could even use preg_split.
foreach(preg_split('/,\s*/', WEBS) as $url) { ...
preg_split() allows you to split your string based on a regular expression. It returns an array. As an example, using this regex, the space following the comma is optional.
# a string like this
foo.com, hello.com,world.com, test.com
# would still split properly to
[
'foo.com',
'hello.com',
'world.com',
'test.com'
]
Regex methods are not always necessary. But I thought I'd show you that a little more control is available when it's necessary.
Aptana is showing you an error because you can't use [] after a func() prior to PHP 5.4. To get around that, you can do things like:
$constants = get_defined_constants(true);
$constants['user']['WEBS'];
But in this case WEBS should be just fine. The only issue you were having is that you needed to convert the string to an array first.

Looks like misuse of constants.
It seems you need a regular variable of array type.
$webs = array('http://google.com', 'http://yahoo.com');
foreach ($webs as $a) {
//do something
}
If you still thinks that constants is what you need - better ask another question, explaining why so, and be told of what you're doing wrong

Related

How to use foreach while only defining the key

So I have this slightly annoying issue: say I have a foreach loop like this:
foreach ($arr as $key=>$value) {
do_something($key);
}
In my eclipse environment, I have turned on the feature that displays warnings for unused variables, which is really helpful. However, it complains for all such occurences, where the $value is not used in the loop.
I was wondering if there is some syntax where I don't use this, like is available for list() :
list(,,$my_var) = some_func();
//these returns an array with 3 elements, but I only need the last one
Note: The obvious would be to use array_keys(), but I don't want a function call; I'm merely asking if there's a shorthand I don't know of, or something like it. This is why the question PHP foreach that returns keys only does not cover what I'm asking.
TBH, I couldn't find any resource to back this answer, it works fine as far as my tests went, BUT I CAN'T SAY FOR SURE WHETHER THIS IS OR ISN'T RECOMMENDED TO USE. (Probably not)
Here is what I came up with:
$arr = array('kN1' => '50', 'kN2' => 400);
//$arr = array('50', 400);
foreach ($arr as $var => $var) { // use same variable for both key and value
print_r($var);
echo '<br>';
}
// kN1
// kN2
Run Viper
To get rid of the warning without introducing too much overhead just unset the unused variable once the loop is done.
foreach ($arr as $key => &$val) {
print_r($key);
}
unset($val);
BTW: I believe one should use a reference to the unused variable (&$val instead of $val). Otherwise you might end up producing a full copy of the variable with each iteration and that might be a costly operation.

is there a compelling reason to use php's list() function?

Can anybody provide an example of when php's list() function is actually useful or preferable over some other method? I honestly can't think of a single reason I'd ever actually want/need to use it..
Got a simple sql result row (numeric), containing, say, an ID and a name?
A simple solution to deal with it, can be:
list($id,$name)=$resultRow;
Edit;
or here's another: you want to know the current key/value pair of an array
list($key,$val)=each($arr);
this can even be put into a loop
while (list($key,$val)=each($arr))
altho you could say a foreach is exactly this; but if the
$arr changes in the meantime, well then it's not. It has its uses. :)
It's a handy function when you know the right hand side is returning an indexed array of a certain size.
list($basename, $ext) = explode('.', 'filename.png');
Note that it can be used in PHP 5.5 with foreach:
$data = [
['a1', 'b1'],
['a2', 'b2'],
];
foreach ($data as list($a, $b))
{
echo "$a $b\n";
}
But if you prefer more verbose code, then I doubt you'll think the above is "better" than the alternatives.

php explode - needing second element

more out of interested...
$_GET['unique'] = blahblahblah=this_is_what_im_interested_in
I know I can get the second element like this:
$words = explode('=', $_GET['unique']);
echo $words[1];
Is there a way to get this in a single line? - that would then 'hopefully' allow me to add that to function/object call:
$common->resetPasswordReply(... in here I would put it....);
like
$common->resetPasswordReply(explode('=', $_GET['unique'])[1]);
I'm just interested to see if this is possible.
PHP supports the indexing on functions if they are returning arrays/objects; so the following would work too:
echo explode('=', $_GET['unique'])[1];
EDIT
This is termed as array dereferencing and has been covered in PHP documentations:
As of PHP 5.4 it is possible to array dereference the result of a
function or method call directly. Before it was only possible using a
temporary variable.
As of PHP 5.5 it is possible to array dereference an array literal.
This should do it for you.
substr($str, strpos($str, "=")+1);
Strangely enough you can 'almost' do this with list(), but you can't use it in a function call. I only post it as you say 'more out of interest' :-
$_GET['unique'] = "blahblahblah=this_is_what_im_interested_in";
list(, $second) = explode('=', $_GET['unique']);
var_dump($second);
Output:-
string 'this_is_what_im_interested_in' (length=29)
You can see good examples of how flexible list() is in the first set of examples on the manual page.
I think it is worth pointing out that although your example will work:-
$common->resetPasswordReply(explode('=', $_GET['unique'])[1]);
it does kind of obfuscate your code and it is not obvious what you are passing into the function. Whereas something like the following is much more readable:-
list(, $replyText) = explode('=', $_GET['unique']);
$common->resetPasswordReply($replyText));
Think about coming back to your code in 6 months time and trying to debug it. Make it as self documenting as possible. Also, don't forget that, as you are taking user input here, it will need to be sanitised at some point.

Is it possible to render the content of a file without using eval in PHP?

I'm trying to create a simple framework in PHP which will include a file (index.bel) and render the variables within the file. For instance, the index.bel could contain the following:
<h1>{$variable_name}</h1>
How would I achieve this without using eval or demanding the users of the framework to type index.bel like this:
$index = "<h1>{$variable_name}</h1>";
In other words: Is it possible to render the content of a file without using eval? A working solution for my problem is this:
index.php:
<?php
$variable_name = 'Welcome!';
eval ('print "'.file_get_contents ("index.bel").'";');
index.bel:
<h1>{$variable_name}</h1>
I know many have recommended you to add template engine, but if you want to create your own, easiest way in your case is use str_replace:
$index = file_get_contents ("index.bel");
$replace_from = array ('$variable_a', '$variable_b');
$replace_to = array ($var_a_value, $var_b_value);
$index = str_replace($replace_from,$replace_to,$index);
Now that is for simple variable replace, but you soon want more tags, more functionality, and one way to do things like these are using preg_replace_callback. You might want to take a look at it, as it will eventually make possible to replace variables, include other files {include:file.bel}, replace text like {img:foo.png}.
EDIT: reading more your comments, you are on your way to create own framework. Take a look at preg_replace_callback as it gives you more ways to handle things.
Very simple example here:
...
$index = preg_replace_callback ('/{([^}]+)}>/i', 'preg_callback', $index);
...
function preg_callback($matches) {
var_dump($matches);
$s = preg_split("/:/",$matches[1]); // string matched split by :
$f = 'func_'.strtolower($s[0]); // all functions are like func_img,func_include, ...
$ret = $f($s); // call function with all split parameters
return $ret;
}
function func_img($s) {
return '<img src="'.$s[1].'" />';
}
From here you can improve this (many ways), for example dividing all functionalities to classes, if you want.
Yes, this is possible, but why are you making your own framework? The code you provided clearly looks like Smarty Template. You could try to look how they did it.
A possible way to run those code is splitting them into pieces. You split on the dollar sign and the next symbol which is not an underscore, a letter or an number. Once you did that. You could parse it into a variable.
$var = 'variable_name'; // Split it first
echo $$var; // Get the given variable
Did you mean something like this?

Extracting array with a suffix

Generally, we can extract an array, and also add an prefix to it, like this
extract($array, EXTR_PREFIX_ALL, "myprefix");
// which will give me output like $myprefix_myarrayvar
But, instead, is there a way to set a suffix instead of prefix? Something like,
$myarrayvar_mypostfix;
First of all, you should never use extract because it can make it very hard to tell where some variables are coming from, never mind possible collisions. You don't save much with extract .. it's really just a tool of laziness.
Anyway, since you asked, no there does not seem to be a way to add a suffix with extract natively, so you would have to do it on your own:
foreach ($array as $key => $val) {
${"{$key}_suffix"} = $val;
}
There is no extract option for that. So you need a workaround. You could either write a boring foreach or prepare the keys prior extraction:
extract( array_combine(preg_replace('/$/', "_suffix", array_keys($array)), $array) );

Categories