PHP: Showing Differences Between Two Strings - php

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.

Related

How would I handle a fatal error while setting up Calendar API on PHP

Following the Google Calendar API quickstart for PHP, I've followed the steps but, got the verification code and instead of getting the expected output " No upcoming events found " I get a
No idea how to move forward from here...
Welcome to StackOverflow!
I've encountered this very same error with numerous WP plugins that had been developed before PHP 5.6 and where programmers have been, well, lazy. Once these plugins get upgraded to PHP 7, exceptions are thrown for things that were mere deprecation warnings a few years ago.
From what I see in your logs, you have a dependency somewhere on Guzzle. According to Guzzle's own documentation, the recent versions require PHP 7.2.5 to work. Therefore, I can only assume that you are:
using a plugin or something similar that is based on an outdated version of Guzzle or you're using Guzzle yourself, but for some reason relying on a deprecated version of it (in the former case, you'd have to pester the plugin developer to update their own dependencies...);
using PHP 7.2 or perhaps even a later version.
You should be using PHP 7.4 or 8.0 as of mid-2021 (everything else has been deprecated), so your installation is fine. It's just the obsolete code coming from that outdated version of Guzzle that requires updating.
So, a simple fix for that issue is to look at the culprit — open on your favourite editor the file C:\xampp\htdocs\api\vendor\guzzlehttp\guzzle\src\Handler\CurlFactory.php and scroll down to line 67 (where the exception was thrown).
According to the trace you've posted, on that line you should have something like:
if (count($some_variable_name_here) [...]) { [...] }
What happened, in this case, was the following:
The count() function requires what PHP calls a Countable object. Generally speaking, historically, these were arrays of some sort.
Lazy programmers often use count() simply to check if the array is empty or not. In the pre-PHP7 days, count(NULL) was defined as being 0 or false, like so many other things in PHP. In other words: if the array was either empty (i.e. initialised but still without any item stored inside) or uninitialised (i.e. still assigned to NULL) or non-existent (i.e. a new variable which had not been declared before), then, by definition, count(NULL) was false.
This allowed lazy programmers to check for a handful of potentially different error conditions with a single if (!count($myArray)) { [...] do this; }. In other words, you would just execute that code inside brackets if $myArray existed, was correctly initialised, and had at least one valid element. All that with a 'simple' check!
Unfortunately, from the perspective of the interpreter and JIT compiler, as well as many other modern optimisation tools used by recent versions of PHP, this is terribly inefficient — besides being very sloppy programming. Starting with PHP 5.6, this misuse of count() became flagged as a warning, then later shown as a deprecated, and finally started throwing exceptions.
So, in your case, whatever is on line 67, count($some_variable_name_here) has been passed an empty/invalid variable/array/object, and while this would be fine before PHP 7, it now throws an exception: count() will not work with so-called 'uncountable' objects, and for all purposes, an unexisting/empty/invalid object is uncountable by definition.
To fix it, all you need to do is to check first if the object is valid and not null, and then you can check if it has any elements inside it. In other words, instead of having something like:
if (count($some_variable_name_here) [...]) {
[... do something ...]
}
change it to:
if (!empty($some_variable_name_here) && is_countable($some_variable_name_here) && count($some_variable_name_here) [...]) {
[... do something ...]
}
Note that empty() is a shortcut for !isset($var) || $var == false, and that PHP evaluates expressions from left to right, aborting as soon as a final result is known. If the variable is empty, the first check will immediately return true and the remaining checks will not even be called; by design, empty() does not throw an error or an exception and is safe to use in all scenarios where variables are in an 'unknown' state.
In many cases, you might get away just by checking if the object $some_variable_name_here is countable or not; a NULL object is not countable, so, it would also fail. In other cases — most frequent these days — you might not really know what has been passed: it might not be a valid, countable object. It might have more than one element, or zero. It might be just garbage and not properly initialised. Or any other possible combination. In those cases, being extra-careful with the checks (as opposed to being sloppy and relying upon PHP to do something useful with an otherwise useless variable/array/object) pays off.
Anyway, I've checked, and the current version of Guzzle's CurlFactory.php still has a count() for function release(), which is what is called before the exception is thrown. However, your own code is clearly different (at the time of writing, the current version has the count() on line 80, not 67), so it's very hard to say if you can correct it easily (there might be other, more subtle errors in the code calling release()...).
One assumes that Guzzle's latest version will fix these and other issues you might have — mostly because they demand PHP 7.2.5 or later, and that means that they have made changes to fix earlier things that didn't work as they should, and such changes were only possible with PHP 7.2.5.
Thus the recommendation is to upgrade your version of Guzzle. If there is any good reason to keep an outdated (and potentially bug-ridden and security-flawed) version around, well, now you know how to do a simple fix. At the very least, your code won't throw an exception; with luck, it will even work as you expect...
Happy hunting!

Fatal error: Call-time pass-by-reference and how to resolved? [duplicate]

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.

Moved php forum to new server and #fsockopen stopped working [duplicate]

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.

PHP 5.4 Call-time pass-by-reference - Easy fix available?

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.

questions about php references

when I was looking for some MVC framework, I got the website:
http://www.phppatterns.com/docs/design/archive/model_view_controller_pattern
however, like the code listed there makes me confused about references.
For example:
$dao=& new DataAccess ('localhost','user','pass','dbname');
$productModel=& new ProductModel($dao);
each instance it makes, it adds '&' before the new operator, what does it exactly mean? the reference to the instance? Actually, I removed all the '&' before all these kind of instances and the code still works perfectly.
Another, codes like :
function ProductView (&$model) {
$this->model=& $model;
}
I really think it could be revised like:
function ProductView (&$model) {
$this->model=$model;
}
Am I right? what's the differences between these two? Actually, like the MVC code example listed above? if you revise the code like I did, the code still works.
Then, I got this post somewhere else:
http://schlueters.de/blog/archives/125-Do-not-use-PHP-references.html
does it make sense? any suggestions about this would be helpful.
Prior to PHP version 5 objects were passed by value and you had to explicitly specify the ampersand to get the object by reference.*
In PHP 5+, all objects are passed by reference and thus using ampersand is redundant.
Furthermore, as of PHP 5.3.0, code like the above will generate a STRICT error of "Assigning the return value of new by reference is deprecated".
If you're curious about the historical use (PHP 4 or before) of "$o =& new Object()" code see php-by-reference (in particular, the accepted answer there provides a good explanation).
To summarise:
in PHP 5 or above, it makes no difference. The code will work as expected with no memory or other differences.
In PHP 5.3 you might get some STRICT notices complaining about this usage (assuming you have STRICT notices turned on).
In PHP 4.x (or earlier) this method was used to prevent unnecessary duplication of objects.
(*) Passing references around is a good thing - no need to create copies of objects when you only need the one instance.

Categories