Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

v4 -> v5: Undefined Variables are Treated Differently #1075

Closed
j-applese3d opened this issue Oct 18, 2024 · 5 comments
Closed

v4 -> v5: Undefined Variables are Treated Differently #1075

j-applese3d opened this issue Oct 18, 2024 · 5 comments

Comments

@j-applese3d
Copy link
Contributor

I tried upgrading a site to version 5, but ran into some issues that I could not resolve.
Specifically, the way Smarty handles variables has changed.

Example:

<?php
// use Smarty\Smarty; // uncomment for v5
require_once 'vendor/autoload.php';

error_reporting(E_ALL);
ini_set('display_errors', '1');

$smarty = new Smarty();
$smarty->display('string:{$TestVarUndefined} is undefined');

Output:

Smarty v4.5.4

Warning: Undefined array key "TestVarUndefined" in [file]_0.string.php on line 18

Warning: Attempt to read property "value" on null in [file]_0.string.php on line 18
is undefined

With a stack trace potentially and more similar warnings.

Smarty v5.4.1

 is undefined

There is no indication that the variable was never assigned.


Why's this a problem?

I would like to know when I make a typo, or forget to assign a variable, but with v5 it'll just become the empty string.

Just use error_unassigned ?

Yes, setting error_unassigned when using v5 will trigger the error, but the problem with this fix is that it will ALSO trigger an error if an undefined variable is used in combination with empty or isset. Like: {if empty($undefinedVar)} Sweet! {else} Oh no! {/if}

PHP's empty and isset work in a special way, suppressing warnings about undefined stuff, and simply returning a boolean.

So, I don't see an easy way to fix this without adding significant complexity to the compiler, so that it treats empty and isset in a special/different way when attempting to access variables/values.

The difference between v4 and v5 is significant in how they work, as v4 compiles to direct array access, whereas v5 uses $_smarty_tpl->getVariable().


The relevant compiled code of the above example is:

// v4
echo $_smarty_tpl->tpl_vars['TestVarUndefined']->value;?>
 is undefined<?php
// v5
echo $_smarty_tpl->getValue('TestVarUndefined');?>
 is undefined<?php

Am I doing something wrong?
Following an anti-pattern?
Is it unreasonable to expect {if empty($neverAssignedVar)} to work, while also expecting an error if {$neverAssigned} is used?

I apologize If I missed something in the docs!

@jontro
Copy link

jontro commented Nov 4, 2024

In v5 you will not get any warnings unless you set $smarty->error_unassigned = true; afaik



use Smarty\Smarty;
require_once 'vendor/autoload.php';

error_reporting(E_ALL);
ini_set('display_errors', '1');

$smarty = new Smarty();
$smarty->error_unassigned = true;
$smarty->display('string:{$TestVarUndefined} is undefined');
 

PHP Warning:  Undefined variable $TestVarUndefined in /Users/jonas/tmp/smartyttest/vendor/smarty/smarty/src/Data.php on line 270

Warning: Undefined variable $TestVarUndefined in /Users/jonas/tmp/smartyttest/vendor/smarty/smarty/src/Data.php on line 270
 is undefined

@jontro
Copy link

jontro commented Nov 4, 2024

Also I think it's a matter of preference in a template language if you want these kind of warnings. Annotating everything with ?? is a pain

@j-applese3d
Copy link
Contributor Author

in v5 you will not get any warnings unless you set $smarty->error_unassigned = true; afaik

Correct. I mentioned this. But it has the side effect of also triggering warnings for {if empty($TestVarUndefined)}is empty{/if}. (and the same for isset)
Which I do not want to be treated as a warning.

I know PHP !== Smarty, but having the behavior of empty and isset mimic that of PHP is my preference.
Unfortunately, I don't think it's possible/easy to accomplish due to the storage/access of variables in Smarty v5.

@jontro
Copy link

jontro commented Nov 5, 2024

@j-applese3d sorry didn't read your question fully. I agree that using isset modifier, empty or ?? should not trigger a warning on error_unassigned

@wisskid
Copy link
Contributor

wisskid commented Nov 18, 2024

Yes, this is a valid issue. However, it has been mentioned in #1063 and #988 so I am closing this one.

@wisskid wisskid closed this as completed Nov 18, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants