2

I have written a validation trait for my model classes, as well as an error reporting library which formats and returns a JSON object of errors, warnings, etc.

In my validation trait, I have this method...

function hasValue($value)
{
  return (isset($value) && !(trim($value) === ''));
}

PHP will throw a warming if I just try to use !(trim($value) in a conditional that tells me the variable is undefined. So, you have to do this...

if (isset($value) && !(trim($value) === ''))
  //Do Something

I created this method to consolidate a very common task requiring two methods into a single method, but I am getting the same warning as if I had used the trim() method alone.

Is there a way to do this without turning off warnings?

EDIT

There seems to be some confusion. I need this to work for variables, and object properties. I'm attempting to turn this...

if (empty($obj->email) && $this->validateEmail($obj->email))
  //Do Something

Into this...

if ($this->validateEmail($obj->email))
  //Do Something

By having my hasValue() method to call on will, and inside the validateEmail() method.

Allenph
  • 1,875
  • 27
  • 46
  • You could try `(isset($value)) ? !(trim($value) === '') : false;` if you're trying to keep it all to one line – Drew Dec 21 '16 at 22:14
  • It's not that I CAN'T write it every time, I'm looking for readability and usability. I don't WANT to write it every time. – Allenph Dec 21 '16 at 22:15
  • maybe I'm missing something, but I do such things like this... `if ( (isset($value)) && (!empty($value))){$value = trim($value); do something } else { // error value was not set or was set to null value }` – Duane Lortie Dec 21 '16 at 22:16
  • I thought you were trying to avoid the PHP Warning you were getting from combining the isset() with the check on $value's value - what I said above should provide the same results your current hasValue function does, but won't push out the warning – Drew Dec 21 '16 at 22:17
  • `if(!empty($value)){}` [docs](http://php.net/manual/en/types.comparisons.php), you can use `if(!empty(trim((string) $value))){}` if desired. – Xorifelse Dec 21 '16 at 22:19
  • @Drew No, I'm just trying to consolidate both methods to one method on a trait. My one-liner works just as well as yours if I write it every time in an `if statement`. – Allenph Dec 21 '16 at 22:19
  • @All, see my edit. I'm trying to have a simple, readable method that can be used on properties and variables, and can be called within callback functions. – Allenph Dec 21 '16 at 22:24
  • @Allenph There is a way to suppress warning messages but believe me this is almost **never** desired. Its done by using the `@` sign before a statement or disable the warning messages from `error_reporting(E_ALL & ~E_WARNING & ~E_NOTICE)`. And if you need this, you're doing it *wrong* – Xorifelse Dec 21 '16 at 22:30
  • @Xorifelse Right. I knew about that. I was wondering if there was a way to avoid doing anything wrong in the first place while still achieving my desired result. – Allenph Dec 21 '16 at 22:34
  • Well, the first issue is that `(isset($value) && !(trim($value) === ''))` is evaluated as one. Remove the outer parenthesis. – Xorifelse Dec 21 '16 at 22:40
  • Let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/131197/discussion-between-xorifelse-and-allenph). – Xorifelse Dec 21 '16 at 22:51
  • Have any of the 2 answers resolved your question? if so mark it, if they were useful at least have the curtsy to up vote. – Xorifelse May 29 '17 at 00:40

2 Answers2

2

The problem you're having is that your function hasValue() evaluates both statements isset($value) and !(trim($value) === '') as one

Instead you should evaluate !(trim($value) === '') if isset($value) equals true. This is done by removing the outer parenthesis.

function hasValue($value){
  return isset($value) && !(trim($value) === '');
  # if this ^^^^ is false this ^^^^ is never executed and no warning generated.
}

That would resolve the warning, however hasValue() sounds more like a function to check if any variable has a value, perhaps do this instead:

function hasValue($value){
  return isset($value) && !empty($value) || is_string($value) && !empty(trim($value));
}

var_dump(hasValue(null));  // false
var_dump(hasValue(true));  // true
var_dump(hasValue(false)); // false
var_dump(hasValue([]));    // false
var_dump(hasValue(''));    // false
var_dump(hasValue(' '));   // false
var_dump(hasValue('a'));   // true

interface validateInterface{
  public static function validateEmail($email);
  public static function validateEmailObj();
}

trait validateTrait{
  static function validateEmail($email){
    return filter_var($email, FILTER_VALIDATE_EMAIL); 
  }
  function validateEmailObj(){
    return filter_var($this->email, FILTER_VALIDATE_EMAIL); 
  }
}

# Implementing an interface is not required, but recommended as traits are easily overwritten.
class MyClass implements validateInterface{
  use validateTrait;

  public $email;

  function __construct($email){
    if(self::validateEmail($email)){
      echo 'works statically inside';
    }

    $this->email = $email;
  }
}

$mail = 'some@email.com';

if(MyClass::validateEmail($mail)){
  echo 'works statically outside class';
}

if((new MyClass($mail))->validateEmailObj()){
  echo 'works with objects';
}

For a longer list of values what isset and empty does see here

Xorifelse
  • 7,878
  • 1
  • 27
  • 38
0

This might be a reasonable place to use the @ modifier to suppress warnings.

if (@trim($value) != '')

If $value is undefined, it will be converted to an empty string. Using @ suppresses the warning message when this happens.

Barmar
  • 741,623
  • 53
  • 500
  • 612
  • This would still not solve the problem of using the function inside other validation functions like `validateEmail`. – Allenph Dec 21 '16 at 22:42
  • I'd rather suggest type juggling, `if( !empty(trim((string)$value)) ){}`. Supressing is a [last](http://stackoverflow.com/a/1369946/4982088) resort – Xorifelse Dec 21 '16 at 22:43
  • You need to use the `@` at the point where you reference the variable that might not be defined. – Barmar Dec 21 '16 at 22:43