2

I have been using PHP 5.4 until now in one of my old projects.

Recently I have decided to upgrade to PHP 7.2

I have around 800 files in my project and old developer team used count() hundreds of time in the project.

In PHP 5.4 even if the variable was not countable it worked as expected but in PHP 7.2 it throws an error.

I could go into each file and change the function but that could take a lot of time and the risk of not changing a couple of function here and there.

Can I extend count() function and write code to make it work as it used to in PHP 5.4?

Is there any other solution to this problem?

I am replacing all if conditions with count($var) functions to is_array($var) && count($var) for now.

Thank you

asked May 14, 2018 at 0:31
3
  • you could deal to the error output, but thats no real solution Commented May 14, 2018 at 0:47
  • @smith you mean that changing from count($var) to is_array($var) && count($var) is not a good idea?? Commented May 14, 2018 at 0:52
  • Yes, that is not a good idea. Imho: good idea to know and define what type your variable is. So you should know is it an array or not long time before (I would say from the beginning) you get to the count() or any other function or method Commented May 14, 2018 at 22:38

4 Answers 4

2

The difference between php 5.4 and php 7+ on that aspect is not that count changed it's behavior, is that php now turned errors into catchable exceptions. Your code was failing silently on production with error_repoting turned off. That is extremely dangerous for the business, as the consistency of your app is unreliable, you should change that asap.

Having that said. Since all errors cannot be turned off anymore by setting your error_reporting to 0 (thats because now they are exceptions rather than errors, and that's really nice, php is no more a super unreliable language). You have to catch those exeptions, which are ErrorException.

Go to the index file of your application and add a try-catch block and swipe the dirty down the carpet again.

try {
 //super buggy app bootstraping
} catch (ErrorException $ex) {
 error_log($ex);
}

Well, i'd rather fix the counts anyway, they are toxic.

Note: is_array($var) && count($var) is not a goo idea, since arrays is not the only countable thing on php, ((is_array($var) || $var instanceof countable) && count($var)) would be a better, but not perfect solution. Also note a bug in php on any version - count(false) - returns 1

answered May 14, 2018 at 3:52
Sign up to request clarification or add additional context in comments.

Comments

2

In other languages like Python you can use decorators to intercept an existing method without modifying the original method.

However PHP does not support decorators so you will need to manually change every location of that call.

answered May 14, 2018 at 0:43

Comments

1

You can use runkit to overload the count() function with your own implementation:

// to override internal functions, this system INI value needs truthy
assert((bool)ini_get('runkit.internal_override'));
// now you can define your own implementation
runkit_function_redefine('count', function ($var) {
 return ((is_array($var) || $var instanceof \Countable) ? count($var) : 0);
});

However, please, consider using this only as a temporary stop gap to ease the pain of 5.4 to 7.2. Because this method is opaque, it'll become a maintenance liability at some point, a liability you probably don't want to linger.

Additionally, note that your conversion of is_array($v) && count($v) does not handle all countable things: i.e., \Generator and \Traversable. The runkit override example above does handle them, though.

answered May 14, 2018 at 0:53

Comments

-1

Fix your code rather, and learn to type. Make sure your count method returns something countable

answered May 14, 2018 at 0:34

Comments

Your Answer

Draft saved
Draft discarded

Sign up or log in

Sign up using Google
Sign up using Email and Password

Post as a guest

Required, but never shown

Post as a guest

Required, but never shown

By clicking "Post Your Answer", you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.