0

I have some code in my WordPress project, that fills up my debug.log-file with garbage. I'm trying to figure out why this is, and it might be something related to the WordPress Core (that is called by my code, none-the-less).

Is there a way, where I can tell PHP to ignore notices for a specific part of my code?

Example

// Imagine, that I'm not sure, if $some_obj->ID exists
// And that $some_obj is passed by some other code, that I don't control
function my_shady_function( $some_obj ){

  $numbers = [ '4', '8', '15', '16', '23', '42' ];  

  if ( in_array( $some_obj->ID, $numbers ) ) { // Mute notices here (ID not set on obj)
    return true;
  }

  $new_obj = new stdObject(); // Forgetting to set property is_true
  if ( $new_obj->is_true ) { // But I'd like notices here!
    return true;
  }
}
Zeth
  • 2,273
  • 4
  • 43
  • 91
  • 1
    Wouldn't it make more sense to check if the ID is set rather than muting the errors. What if there is a different error generated in the future by the code, you won't see it due to not having reporting turned on. – Nigel Ren Jan 29 '22 at 15:10
  • I really wouldn't recommend it, but if you are adamant that you want to mute an error message there use the error control operator (at sign): `@in_array( $some_obj->ID, $numbers )` - https://www.php.net/manual/en/language.operators.errorcontrol.php – Simon K Jan 29 '22 at 18:34

3 Answers3

0

Using @

As a comment suggest, it can be solved using @:

function my_shady_function( $some_obj ){

  $numbers = [ '4', '8', '15', '16', '23', '42' ];  
  $is_in_array = @in_array( $some_obj->ID, $numbers ); // Mute!
  if ( $is_in_array ) { 
    return true;
  }

  $new_obj = new stdObject();
  if ( $new_obj->is_true ) { // Not muted!
    return true;
  }
}

Using error_reporting

One way would be to change error_reporting before and after code where I don't want to see notices

Inspired by this post, setting error_reporting in the code I figured I could do this:

function my_shady_function( $some_obj ){

  $original_error_reporting = error_reporting();
  error_reporting( $original_error_reporting & ~E_NOTICE);
  $numbers = [ '4', '8', '15', '16', '23', '42' ];  
  if ( in_array( $some_obj->ID, $numbers ) ) { // Mute notices here (ID not set on obj)
    return true;
  }
  error_reporting( $original_error_reporting );

  $new_obj = new stdObject(); // Forgetting to set property is_true
  if ( $new_obj->is_true ) { // But I'd like notices here!
    return true;
  }
}

I'm not sure, if this is the best way to go.

Zeth
  • 2,273
  • 4
  • 43
  • 91
  • Be aware that if you use the `@` mute operator, but your code (or framework) has an error handler defined, it will still be called, and the muted warning needs to be skipped at that level ([ref](https://www.php.net/manual/en/language.operators.errorcontrol.php)). The solution where the problem code is surrounded by `error_reporting` define/redefine seems like more trouble than actually fixing the code. Short version, I'm rather sure this isn't the way to go, not if you expect to be working with your code into the future. For throw-away code, maybe. – Markus AO Feb 03 '22 at 05:06
0

I think the best way is to check $some_obj->ID like is_int() or something else depend on this variable.

if(is_int($some_obj->ID) && in_array($some_obj->ID, $numbers)) {

in this case, in_array will not executed, when is_int is false.

daniel
  • 273
  • 2
  • 7
  • `is_int($obj->ID)` produces a warning if the key `ID` isn't defined. Please make sure your code works as expected before posting. Also, `is_int('4') === false`, because OP has his numbers as strings. `is_numeric()` would return true, but it would still throw a warning. – Markus AO Feb 03 '22 at 04:50
0

In the tune of my answer to your question on check if variable isset and iterable, we can harness the power of null-coalescence to provide your code with default values.

$numbers = [ '4', '8', '15', '16', '23', '42' ];  

if ( in_array( $some_obj->ID ?? 'duck', $numbers ) ) {
    return true;
}

The above simply provides a default value that isn't going to be in your array. You don't have to use "duck", you can use uniqid() or whatever other value that surely isn't found in the haystack.

Next, dealing with the expected but omitted boolean:

$new_obj = new stdObject(); // Forgetting to set property is_true
if ( $new_obj->is_true ?? false ) { // But I'd like notices here!
    return true;
}

If object has no is_true property, we default to false, and this evaluates as if(false).

If you mute warnings, and more so, crank down error reporting, you'll be chasing bugs high and low down the road, when clear feedback is lost. Do this at the risk of your future sanity.


I'll throw in a bonus, seeing as your $numbers array above is made of numeric strings. If you have declare(strict_types=1); on, you'll get fatal errors when using "string-numbers" or "number-strings" for functions that expect int or string types. Examples:

<?php declare(strict_types=1);

$number = '4'; // "string-for-int"
    
$substring = substr('hello', 0, $number);
// : TypeError: substr(): Argument #3 ($length) must be of type ?int, 

$substring = substr('hello', 0, (int) $number);
// : No problem

$string = 123; // "int-for-string"

$substring = substr($string, 0, 2);
// : TypeError: substr(): Argument #1 ($string) must be of type string, int given 

$substring = substr((string) $string, 0, 2);
// : No problem

Using strict_types is really quite helpful for ensuring that sloppy values doesn't simply get coerced into the types expected, transparently resulting in anomalous behavior.

If you're dealing with legacy code featuring strange data, strict types will teach you where things go wrong, and type-casting will help you patch things up after verifying that only values that can reasonably be coerced are being used.

To illustrate, you have deeper issues if you come across e.g. substr($str, 2, $end) where $end = 'duck', given that (int) 'duck' === 0. On the other hand, e.g. anything from a query string is, well, a string; but if e.g. you had a form UI submitting only basically valid numbers, you could reasonably typecast substr($str, 0, (int) $_GET['end']) and deflect type errors.

Markus AO
  • 4,771
  • 2
  • 18
  • 29