7

I'm building a class with a number of input validations, and I've decided to place them inside a __set method (I'm not sure if this is proper form as I have limited OOP experience). This seems to work fine, throwing the proper errors when invalid values are passed from outside the class. However, if a variable is modified inside the class the _ _set method seems to be ignored alltogether.

Any insight would be hugely appreciated

//RESULT:::::::::::::::::::::::::::::::
// PASS: Testing : hello
// PASS: Testing exception handling
// __SET: Setting b to 123
// PASS: Testing with valid value: 123
// FAIL: Testing exception handling World2



 <?php
class Test {
        public $a;
        private $b;

        function __set( $key, $val ) {

                switch( $key ) {
                        case 'b':
                                if( !is_numeric( $val ) ) throw new Exception("Variable $b must be numeric");
                                break;
                }

                echo ( "__SET: Setting {$key} to {$val}<br/>" );
                $this->$key = $val;
        }
        function __get( $key ) { return $this->$key; }
        function bMethod() {
                $this->b = "World2";
        }

}

$t = new Test();

//testing a
try {
        $t->a = "hello";
        echo "PASS: Testing $a: {$t->a}<br/>";
} catch( Exception $e)  {
        echo "FAIL: Testing $a";
}

//testing b
try {
        $t->b = "world";       
        echo "FAIL: Testing $b exception handling<br/>";
} catch( Exception $e ){
        echo "PASS: Testing $b exception handling<br/>";
}

//testing b with valid value
try  {
        $t->b = 123;
        echo "PASS: Testing $b with valid value: {$t->b}<br/>";
} catch( Exception $e) {
        echo "FAIL: Testing $b";
}

//bypassing exception handling with method
try {
        $t->bMethod("world");
        echo "FAIL: Testing $b exception handling {$t->b}<br/>";
} catch( Exception $e ) {
        echo "PASS: Testing $b exception handling<br/>";
}
1
  • This had me foxed for at least an hour... Commented Nov 25, 2015 at 15:59

2 Answers 2

11

Read the definition of __set: "__set() is run when writing data to inaccessible members." Inaccessible is key here. From within the class, all members are accessible and __set is bypassed. Overloading

Sign up to request clarification or add additional context in comments.

1 Comment

Unfortunately I'm out of votes today, but this is correct. I ran into this issue trying to emulate getters/setters from other languages. It just doesn't work the same.
6

The documentation at the php documentation says:

__get() is utilized for reading data from inaccessible members.

So, you can do something like:

<?php
class Test {
    private $_params = array();

    function __set( $key, $val ) {
        ...
        $this->_params[$key] = $val;
    }

    function __get( $key ) {
        if (isset($this->_params[$key])) return $this->$key;
        throw Exception("Variable not set");
    }

    ...
}

1 Comment

This feels like a bit of a hack, but it actually does exactly what I wanted to do; variable calls inside class methods can't call the variables directly, so they use the __set and __get function. Thanks!

Your Answer

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.