The following code causes a 'deprecated' error in PHP 5.3... Is there a substitute for it?
$this->widgets[$widget_class] = & new $widget_class();
It'd be nice if you could specify what exactly the error message says, but I'm guessing it's informing you that object assignment by reference (=&) is deprecated. Objects are always assigned and passed by reference as of PHP 5, so including & is unnecessary. Simply drop the reference operator:
$this->widgets[$widget_class] = new $widget_class();
Related
Is there any way to easily fix this issue or do I really need to rewrite all the legacy code?
PHP Fatal error: Call-time pass-by-reference has been removed in ... on line 30
This happens everywhere as variables are passed into functions as references throughout the code.
You should be denoting the call by reference in the function definition, not the actual call. Since PHP started showing the deprecation errors in version 5.3, I would say it would be a good idea to rewrite the code.
From the documentation:
There is no reference sign on a function call - only on function definitions. Function definitions alone are enough to correctly pass the argument by reference. As of PHP 5.3.0, you will get a warning saying that "call-time pass-by-reference" is deprecated when you use & in foo(&$a);.
For example, instead of using:
// Wrong way!
myFunc(&$arg); # Deprecated pass-by-reference argument
function myFunc($arg) { }
Use:
// Right way!
myFunc($var); # pass-by-value argument
function myFunc(&$arg) { }
For anyone who, like me, reads this because they need to update a giant legacy project to 5.6: as the answers here point out, there is no quick fix: you really do need to find each occurrence of the problem manually, and fix it.
The most convenient way I found to find all problematic lines in a project (short of using a full-blown static code analyzer, which is very accurate but I don't know any that take you to the correct position in the editor right away) was using Visual Studio Code, which has a nice PHP linter built in, and its search feature which allows searching by Regex. (Of course, you can use any IDE/Code editor for this that does PHP linting and Regex searches.)
Using this regex:
^(?!.*function).*(\&\$)
it is possible to search project-wide for the occurrence of &$ only in lines that are not a function definition.
This still turns up a lot of false positives, but it does make the job easier.
VSCode's search results browser makes walking through and finding the offending lines super easy: you just click through each result, and look out for those that the linter underlines red. Those you need to fix.
PHP and references are somewhat unintuitive. If used appropriately references in the right places can provide large performance improvements or avoid very ugly workarounds and unusual code.
The following will produce an error:
function f(&$v){$v = true;}
f(&$v);
function f($v){$v = true;}
f(&$v);
None of these have to fail as they could follow the rules below but have no doubt been removed or disabled to prevent a lot of legacy confusion.
If they did work, both involve a redundant conversion to reference and the second also involves a redundant conversion back to a scoped contained variable.
The second one used to be possible allowing a reference to be passed to code that wasn't intended to work with references. This is extremely ugly for maintainability.
This will do nothing:
function f($v){$v = true;}
$r = &$v;
f($r);
More specifically, it turns the reference back into a normal variable as you have not asked for a reference.
This will work:
function f(&$v){$v = true;}
f($v);
This sees that you are passing a non-reference but want a reference so turns it into a reference.
What this means is that you can't pass a reference to a function where a reference is not explicitly asked for making it one of the few areas where PHP is strict on passing types or in this case more of a meta type.
If you need more dynamic behaviour this will work:
function f(&$v){$v = true;}
$v = array(false,false,false);
$r = &$v[1];
f($r);
Here it sees that you want a reference and already have a reference so leaves it alone. It may also chain the reference but I doubt this.
I have a plugin in my forum which throws a warning.
I want to fix the problem, but firstly, I want to hide the warning message to the users.
I know I can change it globally, but I just want to do it for some lines.
How can I do this?
$bbcode_parser =& new vB_BbCodeParser($vbulletin, fetch_tag_list());
gives the error:
Warnung: Assigning the return value of new by reference is deprecated in ..../includes/garage_func_var.php (Zeile 6411)
I already know I need to use # but where do I put this?
# can be used to suppress warnings, notices and errors.
Fatal errors are displayed in PHP 7 which breaks the script.
# can be used before variables, functions, include calls, constants and so forth but cannot be prepended to function or class definitions, conditionals, loops and so forth.
So for example, to hide an undefined property error:
Class Cars{
}
$obj = new Cars();
echo #$obj->idontexist;
As to your specific problem:
#$bbcode_parser =& new vB_BbCodeParser($vbulletin, fetch_tag_list());
should fix it.
While the mentioned deprecated warning message is displayed in PHP 5, the following will be displayed in PHP 7 since it was deprecated in the upgrade.
PHP 7 Note:
Parse error: syntax error, unexpected 'new' (T_NEW)
Use # only as an absolute last resort. It is considered bad coding to use # as slows things down and moreover creates headaches for programmers (including yourself) in the future when trying to debug. This is really frowned upon.
You should:
Hide warnings only for that call using a function using set_ini
Use "try" in php to manage errors.
My site has a deprecated error at this line:
$obj =& new $class($table,$primkeyArr,$this);
it is because of &. It gives this error:
Deprecated: Assigning the return value of new by reference is deprecated in ....
It is a issue in php 5.3.
If I remove the & from this line, the error does away. But I don't know if it causes any problem if I put my site on a server with lower PHP version (5.2) or not.
Will removing the & work ok both in PHP 5.2 and in PHP 5.3?
In PHP 5, objects are handled in a reference-like manner by default. So removing the & probably won't change anything.
But as assigning by reference breaks old references, there might still be a difference.
It's not deprecated to return a reference but to not reflect that in your functions oder methods signature. There has to be an & before the name as well as when assigning the returned value.
public function &getValue()
{
return $this->value;
}
...
$myValue = &$obj->getValue();
The manual will tell you more.
http://php.net/manual/en/language.references.pass.php
It's a mere warning. You don't really need it, but the short answer is that it will only throw warnings. Depending on the level of error_handling in your php config will depend on if you see it on other 5.3 systems.
I am getting a deprecated warning because of a library I am using. The statement is the following :
$this->_ole =& new OLERead();
The thing is I don't see why one would want to use & new in an instantiation.
If I am not mistaken, the & operator tells PHP to copy the reference to the instance, and not the instance itself. But in that case, isn't it pointless to ask for a copy of a reference that isn't stored ?
But since I don't exactly know how new exactly works, maybe this was supposed to save some obscure garbage collection, or something like that.
What do you think about that ?
From the documentation:
As of PHP 5, the new operator returns a reference automatically, so assigning the result of new by reference results in an E_DEPRECATED message in PHP 5.3 and later, and an E_STRICT message in earlier versions.
The library you use was probably developed for PHP 4.
Helpful information about why this was used can also be found in the migration guide:
In PHP 5 there is a new Object Model. PHP's handling of objects has been completely rewritten, allowing for better performance and more features. In previous versions of PHP, objects were handled like primitive types (for instance integers and strings). The drawback of this method was that semantically the whole object was copied when a variable was assigned, or passed as a parameter to a method. In the new approach, objects are referenced by handle, and not by value (one can think of a handle as an object's identifier).
That's an idiom for PHP4 compatibility. Objects were passed as copies per default there, and this is a workaround to always have references to an instance.
In PHP4, new returned a value and not a reference.
This is not the case in PHP5.
If you write $this->_old =& new OLERead(); a changement of _ole in any object will updates all references to the new object.
This is not the case without & .
EDIT: And yes, in previous versions of PHP, object were passed by copy. At the end, this is quite hard to have a consistent behaviour accross versions.
Is there a functional String Difference Highlighting class/function out there for PHP?
This has been asked before Highlight the difference between two strings in PHP but the answers given suggest PEAR's Text_Diff.
I tried using Text_Diff and found it was giving me a bunch of STRICT NOTICES and the examples given returned empty strings.
Errors like:
array_walk() expects parameter 2 to be a valid callback, non-static method Text_Diff::trimNewlines() should not be called statically
Open '/framework/gii/components/Pear/Text/Diff.php' file. Locate the function trimNewlines and add a word static. Something like this:
static function trimNewlines(&$line, $key)
This may help.
I think it means that one or more of the functions that PEAR package uses is not backward compatible with some earlier version(s) of PHP. Maybe just suppress the notice using error_reporting or (dare I say) with the error suppression operator '#'.
You could contact the maintainer of Text_Diff and report the errors. 5.3 is relatively new and it introduces a bunch of changes, so there are many projects that haven't been upgraded yet.