2

I have my own class for templates. In this class, I replace string likes {NEXT_PAGE} to

<?php echo $tpl->vars["NEXT_PAGE"]; ?>

But sometimes happen, that this index doesn't exists.

I found topic PHP: is_array on $arr['key'] with non existing 'key' and I know how to check if some index exists.

My question is, what is better to improve performance.

  1. Always check if index exist and if yes, print it
  2. Just print it without checking if index exists.

First solution is great, no warning, no errors, no notices, but I go through array twice, first time to check it, second time to print it. Need more CPU time.

Second solution just try to find it, if it exists print it, otherwise print empty string, it's OK for me, and warnings I can disable by error_reporting


So what is better? I think that second solution with disabling warnings. PHP always have to check if index exists, but when I check it too, it is checked twice. Am I right?

Just to be clear, accessing to index which doesn't exists is max 3% of all accessing to this array.


Example I have a form, where I put back login name, if pass is incorrect. When I replace {LOGIN_NAME} by <?php echo $tpl->vars["LOGIN_NAME"]; ?> I save this new file like a PHP script, so later I just run this, no replacing again!

So my compiled script is something like this

<form ...>
<input type="login" ... value="<?php echo $tpl->vars["LOGIN_NAME"] ?>" />
(pass etc...)
</form>

So when someone visit this page for the first time LOGIN_NAME isn't set, PHP can't print anything but it's OK, field is still empty. If form is send, script add to LOGIN_NAME sent login name and then field isn't empty.

Community
  • 1
  • 1
Arxeiss
  • 976
  • 16
  • 34
  • `vars["NEXT_PAGE"])) ? $tpl->vars["NEXT_PAGE"] : ''; ?>` it shouldn't need to process a whole array to do this, because it's a direct hash lookup each time – Mark Baker May 31 '13 at 11:14
  • I think first solution, less chances be confused. – maximkou May 31 '13 at 11:16
  • @MarkBaker, for arrays there's "array_key_exists" function instead of "isset". – maximkou May 31 '13 at 11:17
  • @maximkou - I know, isset() is faster because it's a language construct rather than a function – Mark Baker May 31 '13 at 11:19
  • 1
    Good to point out array_key_exists()...it just checks if the key exists, unlike isset() which also runs isset() on the corresponding array value, if found. – Matt Browne May 31 '13 at 11:21
  • @MarkBaker, yes, i agree, but faster is not always better. – maximkou May 31 '13 at 11:21
  • No, but in this case the results are almost identical (isset() will return FALSE) if the value is set but contains a NULL value)... so why should the array_key_exists() function be used instead, with the overhead of a function call? – Mark Baker May 31 '13 at 11:24
  • @Arxeiss, I would make two modes - development and production. Respectively in dev mode - show errors and in production - log errors. – maximkou May 31 '13 at 11:25
  • It depends on your scenario: using the @ operator to supress error messages is costy (slow). So if it happens once per 1000 items, it´s ok. it it happens once per 5 items, check for key existence. How ever, PHP uses fully balanced trees to index arrays, so it´s fast either way. – Zsolt Szilagyi May 31 '13 at 11:44
  • I added some example to my post. @Zsolt Szilagy I can hide warning globaly by `error_reporting` so no @ needed. So you said, that searching is so fast, that it depend on me what I prefer? Thanks – Arxeiss May 31 '13 at 12:39
  • @Arxeiss I would use the @ operator nevertheless. You should always aim to make a script clean even under error reporting : notice conditions. (you might turn it on once you have to tackle a bug). Any error throws are always slow (the error handler is called, you can only supress the *reporting*), so I would rather stick to array_key_exists. Check out http://stackoverflow.com/questions/16675753/php-fastest-way-to-handle-undefined-array-key – Zsolt Szilagyi May 31 '13 at 12:49
  • Thanks, can you wrote it as answer, not comment? Because your 2 last comments are exactly what I want. Some solution and reason why this is great and other is wrong. And it is only answer I can marked as "accepted answer". – Arxeiss May 31 '13 at 12:55

4 Answers4

3

You are currently looping through pattern matches in a file and then replacing the matches with the corresponding template var, if it is set.

Why don't you come at the problem from the other side?

Loop through your template vars and replace pattern matches in the file. Then, afterwards, replace any remaining pattern matches with the empty string.

foreach ($tpl->vars as $key => $val) {
    $template = str_replace("{$key}", $val, $template);
}
$template = preg_replace('/{(.+?)}/', '', $template);

Update: Since you want to write a php string into the template instead of the actual value, the code would look like this:

foreach ($tpl->vars as $key => $val) {
    $template = str_replace("{$key}", "<?php echo \$tpl->vars['$key']; ?>", $template);
}
$template = preg_replace('/{(.+?)}/', '', $template);

Then $template would contain a string which you write to the cache. The principle is the same.

Joe Green
  • 1,745
  • 1
  • 12
  • 17
  • No, I replace all occurrences in file, then I cache it as PHP script, later just calling this PHP script. I'll add example to my question in a minute. – Arxeiss May 31 '13 at 12:27
1

Is your system performance critical? How many lookups will you perform per second?

A post on how isset() is faster than array_key_exists(). http://ilia.ws/archives/247-Performance-Analysis-of-isset-vs-array_key_exists.html

Think about what does it mean in terms of design to have or not have this key in the array. Should it always be there? Is the model valid in each case?

My current understanding is that the lookup is required.

lb.
  • 5,666
  • 3
  • 17
  • 16
0

You could put @ in front of your echo statement, which would suppress any errors. There are probably also other ways of writing a template engine that don't require array access in this way (perhaps using a custom object instead, or the extract() function), but the @ trick seems simplest here.

Matt Browne
  • 12,169
  • 4
  • 59
  • 75
  • I agree with @MarkBaker, suppressing errors is never a good solution. – Niklas Modess May 31 '13 at 11:25
  • In most cases I would not recommend this approach, but here it seems like it would probably be the most performant without any real downside. For the 97% of the time that the array key exists, I think this would be fastest, of course it should be benchmarked to be sure. – Matt Browne May 31 '13 at 11:26
  • 1
    But now I see @JoeGreen's solution, which I think is better, so my vote would be for that. – Matt Browne May 31 '13 at 11:32
0

you can check if an index of a variable exists with the isset function:

if (isset($tpl->vars["NEXT_PAGE"]))
{
}
MjeOsX
  • 375
  • 4
  • 12