如何从PHP中的其他类使用STATIC方法访问类属性?

the question title seems pretty confusing, but this is what i want to achieve.

i have two classes

1. Category
2. Validation

In Category Class i have the following Class Property

public  $error;    //holds all errors in an array.
private $dbh;      //Database object Handle(PDO).
private $validate; //Holds Validation Object
private $data = array('categoryName',
                      'subCategoryName',
                      'prefix',
                      'categoryId',
                      'subCategoryId');

in Validation Class i have defined a method.

public function required($fields = array()) {
    foreach($fields as $field) {
        if(empty(__CLASS__::data[$field])) {

        }
    }
}

now when i call the method $this->validate->required() within the class Category it should check the condition if $data[field] of Category class is empty or got any value in it. hence i have used the following syntax which does not seems to work. if(empty(__CLASS__::data[$field]))what the condition should check is if the class property $data of the class it is being called from (it is class Category in this case) is empty or not. what is the correct syntax for fetching the class property dynamically?

thank you..

Give your Category instance as parameter to your validation function. You should have something like this:

public function required($category, $fields = array()) {
    foreach($fields as $field) {
        if(empty($category->data[$field])) {

        }
    }
}

$this->validate->required($this);

Also you do not use a static method, as mentioned in your questions headline in your example. If you have a static function in Validation you would call it like this:

Validation::required($this);

In this case, you do not need a reference to a Validation instance in your Category class at all.

Use get_class_vars(): $class_vars = get_class_vars(__CLASS__);. Be aware of possible visibility problems for private $data, as according to the documentation get_class_vars() returns the properties that can be accessed from the current scope.

I think the best way would be, to not access the data in Category directly, but to add it as a parameter to your validation method.

Like:

public function required($fields = array(), $required = array()) ...

Because otherwise, you're purposly working around encapsulation.

If you still want to go this way, declare $data as public static, or use php reflection.

Not sure what your are trying to do , if you want to access Category properties in Validation, you can pass $data to your function call:

// you could call required() this way ...
$this->validate->required($data);

// In validate::required()
public function required($fields = array()) {
  foreach($fields as $field) {
      if(empty($data[$field])) {

      }
    }
}

Now, of course you could set the data as static, but it is not a good use of static variables, especially since you already have a reference in parent class.

private static $data = array('categoryName',
                             'subCategoryName',
                             'prefix',
                             'categoryId',
                            'subCategoryId');

 // and access it through :: operator in validation.
  public function required() {
    $fields = Category::$data;
  foreach($fields as $field) {
      if(empty($data[$field])) {

      }
    }
 }

So, I think you are on the right track without using static, except one thing you are missing, if you want validation object inside category, don't forget to create an instance of it, here is a simple way to pass your instance in a dependecy-injected manner that makes for easier testing:

  class Category{
    private $validate; //Holds Validation Object


    // constructer with type hinting, 
    public function  __construct(Validator $validation){

    // set validator object to this objects property.
    $this->validate = $validation;  
    }

 }

 //create validator instance
 $validator = new Validator;

 // Pass it off to category,

 $category = new Category($validator);