I have just upgraded to Symfony 2.7.4 from 2.7.3.
After the upgrade a form that worked under 2.7.3 is now throwing this error
An exception has been thrown during the compilation of a template ("Notice: Undefined variable: test")
There is no variable in the template named 'test'.
The exception also shows this code snippet:
if ($function instanceof Twig_SimpleFunction && $function->isDeprecated()) {
$message = sprintf('Twig Function "%s" is deprecated', $function->getName());
if ($test->getAlternative()) {
$message .= sprintf('. Use "%s" instead', $function->getAlternative());
}
$message .= sprintf(' in %s at line %d.', $this->parser->getFilename(), $line);
This snippet suggests that twig is testing for a deprecated function and, if true, Symfony is objecting to an undefined variable $test.
Has anyone experienced this error or can give advise on how to resolve?
Could this error be caused indirectly by something else in the form?
You should upgrade to Twig 1.21.2 see http://symfony.com/blog/twig-1-21-2-released
Related
I am implementing a plugin controller CLASS for client created custom plugins.
Since the names of the classes of each plugin could very well end up clashing with other plugins already installed, I want to make sure we don't get fatal errors when a new plugin comes in.
I want to report to the user that the new plugin is clashing with an already installed one.
So basically atm I testing with 2 files both containing exactly the same code and am getting:
Fatal error: Cannot declare class [myclassname], because the name is already in use
I have tried catching this with no success using:
try {
include_once $file;
} catch (ClosedGeneratorException|DOMException|ErrorException|IntlException|LogicException|BadFunctionCallException|BadMethodCallException|DomainException|InvalidArgumentException|LengthException|OutOfRangeException|PharException|ReflectionException|RuntimeException|OutOfBoundsException|OverflowException|PDOException|RangeException|UnderflowException|UnexpectedValueException|SodiumException $ex) {
echo "Unable to load file.";
}
All these I got from Lists of Throwable and Exception tree as of 7.2.0 in https://www.php.net/manual/en/class.exception.php
The manual specifies that:
The thrown object must be an instance of the Exception class or a
subclass of Exception. Trying to throw an object that is not will
result in a PHP Fatal Error.
Is it possible that this is not an object of instance/suclass of the Exception class?
What am I missing?
Short answer: no, you're not missing anything. Declaring a duplicate class name can't be caught in any version of PHP (including 8.0.0 as far as the alpha releases). See https://3v4l.org/2TLA3
For some additional background, PHP does sometimes move errors like these underneath the Throwable hierarchy, so that they can be detected at runtime. PHP 7 added support for catching an attempt to instantiate a missing class, and 7.3 added support for catching an attempt to extend a missing class. See https://3v4l.org/BDnm9 for a brief demo of those.
In the end, to avoid this fatal error I decide to parse the files for the first available class declaration using tokens as follows:
public function getClassInFile($filenpath) {
$src = $this->uncommentFile($filenpath);
$class ='';
if (preg_match('/class[\s\n]+([a-zA-Z0-9_]+)[\s\na-zA-Z0-9_]+\{/', $src, $matches)) {
$class = $matches[1];
}
return $class;
}
public function uncommentFile($filenpath) {
$fileStr = file_get_contents($filenpath);
$newStr = '';
$commentTokens = array(T_COMMENT);
if (defined('T_DOC_COMMENT'))
$commentTokens[] = T_DOC_COMMENT; // PHP 5
if (defined('T_ML_COMMENT'))
$commentTokens[] = T_ML_COMMENT; // PHP 4
$tokens = token_get_all($fileStr);
foreach ($tokens as $token) {
if (is_array($token)) {
if (in_array($token[0], $commentTokens))
continue;
$token = $token[1];
}
$newStr .= $token;
}
return $newStr;
}
In this way, I can check whether the class I am expecting to find is in there, or if the class in there already exists, thus avoiding to include_once altogether in these cases.
Problem solved.
When PHP emits a PHP Notice to the log, it contains the file name and the line number where the problem occurred. In the case of a large application, this often isn't enough to reproduce the problem. What would really help is some additional information, most obviously the URL that was being called at the time this notice occurred.
Is there a way to customize the PHP Notice message in PHP >= 7?
Create your own error handler and catch the notices then log the message with whatever information you need. The code below produces the following the PHP error log file.
[27-Feb-2019 13:55:09 America/New_York] 8 Undefined variable: hello
from URI /customnotice.php
function myErrorHandler($errno,$errstr, $errfile, $errline) {
if ($errno == 8) { // this is a notice
error_log($errno . ' ' . $errstr . ' from URI ' . $_SERVER['REQUEST_URI']);
}
}
$old_error_handler = set_error_handler("myErrorHandler");
echo $hello; // will throw a notice for testing
I try to used to an old customized module in my Prestashop that runs with php 7.0.
I got an error and no idea...
Fatal error: Uncaught Error: Call to undefined method Product::getFrontFeaturesHiddenByNameStatic()
And here is the line of code.
$feature = Product::getFrontFeaturesHiddenByNameStatic((int)($params['cookie']->id_lang), $product['id_product'],'_Descriptif accueil');
And that function is defined in "override" folder.
public static function getFrontFeaturesHiddenByNameStatic($id_lang, $id_product, $featureName) {
self::getFrontFeaturesStatic($id_lang, $id_product);
if( isset(self::$_frontFeaturesCacheHidden[$id_product.'-'.$id_lang]) )
foreach(self::$_frontFeaturesCacheHidden[$id_product.'-'.$id_lang] as $feature) {
if( $featureName == $feature["name"] )
return $feature;
}
return null; // nothing has been found
}
Thanks in advance !
I think I found the solution.
Actually the override definition was not in the right folder.
It was in override/classes and failed, while set in modules/mymodule/override/classes, it seems to work fine...
Thank for your help!
I want to receive the error message in php before it gets executed. Basicly what i mean is that if I would have a bad code:
// This code is incorrect, I want to receive the error before it gets handled!
$some_var = new this_class_is_not_made;
Now that class does not exist, so it would be handles by the default error handler in php. But I want to disable the normal error handler and create my own.
Another example:
somefunction( string some_var ); // some_var misses the variable prefix. ( $ )
Example error message:
Fatal error: function 'some_var' is not defined in line: $x!
And this error would be: somefunction( string some_var );
But how would I receive the messages but also disable the normal error system?
EDIT: Making the error system execute a user-defined function
// I would want the error system to execute a function like this:
function(string $errorMessage, int $error_code){
if($error_code < 253){ return "Fatal error"; }
if($error_code < 528 && $error_code > 253){ return "Warning"; }
}
Answer found: By: ShiraNai7
try
{
// Code that may throw an Exception or Error.
}
catch (Throwable $t)
{
// Executed only in PHP 7, will not match in PHP 5
}
catch (Exception $e)
{
// Executed only in PHP 5, will not be reached in PHP 7
}
In PHP 7.0.0 or newer the code will throw Error exception if this_class_is_not_made doesn't exist.
try {
$some_var = new this_class_is_not_made;
} catch (Error $e) {
echo $e->getMessage();
}
Note that that this will also catch any other Error exceptions in case this_class_is_not_made does exist and causes some other error along the way.
In PHP versions prior to 7.0.0 you're out of luck - fatal errors always terminate the main script.
It might be a better idea to use class_exists() instead:
if (class_exists('this_class_is_not_made')) {
$some_var = new this_class_is_not_made;
}
This works in all PHP versions that support classes.
I'd like to use stdClass to store options for some methods, instead of passing huge lists of variables (inspired by javascript-style coding)
However, I'd like to make sure I'm always getting an instance of stdClass as an argument. I know I can add a hint in the argument (gb::search below) but when I deliberately try to break it, I'm not sure how to handle the error.
Any tips?
class gb extends CI_Model {
protected $searchtypes = array('full','partial');
protected $endpoint = "https://local.endpoint";
function __construct() {
parent::__construct();
// sample search
$options = new stdClass();
$options->term = 'sample search';
$options->type = 'full';
$this->search($options);
}
function clean_term($term){
$term = trim($term);
return $term;
}
function search(stdClass $options){
$term = $options->term;
$type = $options->type;
// make sure we're doing a valid search
if (!$term || !in_array($type, $this->searchtypes)) {
return false;
}
$term = $this->clean_term($term); // etc
}
The error it throws is something like:
A PHP Error was encountered
Severity: 4096
Message: Argument 1 passed to gb::search() must be an instance of stdClass, null given, called in /application/models/gb.php on line 20 and defined
Filename: models/gb.php
Line Number: 29
A PHP Error was encountered
Severity: Notice
Message: Trying to get property of non-object
Filename: models/gb.php
Line Number: 31
A PHP Error was encountered
Severity: Notice
Message: Trying to get property of non-object
Filename: models/gb.php
Line Number: 32
Any ideas how to approach this from a CodeIgniter point of view?
if I remember - mistyped argument should raise E_RECOVERABLE_ERROR, so, it triggers error handler but execution continues. So, you have two options basically.
One is to throw exception in error handler when E_RECOVERABLE_ERROR is encountered. To halt execution.
Another - check type with instanceof stdClass and do what you suppose - raise exception or return something.
UPDATE In your case your framework (CI is for CodeIgniter?) sets error handler (somewhere using set_error_handler). So, after logging or printing error message execution continues. (If there was not handler you would get fatal error). Just test type of argument manually:
function search(stdClass $options){
// test type for sure, because of recoverable error
if (!($options instanceof stdClass)) {
return false; // or throw new InvalidArgumentException('Parameter should be instance of stdClass');
}
$term = $options->term;
$type = $options->type;
// make sure we're doing a valid search
if (!$term || !in_array($type, $this->searchtypes)) {
return false;
}
$term = $this->clean_term($term); // etc
}