#1
  1. Mad Scientist
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Oct 2007
    Location
    North Yorkshire, UK
    Posts
    3,661
    Rep Power
    4123

    Help, I'm using eval()!!!


    I've written some code and it uses eval()

    I'd rather it didn't use eval() so I'm asking around for some ideas on how to proceed.

    Basically, I have setter and getter methods in a singleton class

    each method takes two arguments, $key and $value

    To begin with it was pretty simple and I would do

    PHP Code:
    public function setSetting($key,$value) {
        
    $this->settings[$key] = $value;

    but then I wanted $this->settings to be a multi-dimensional array, like

    PHP Code:
    $this->settings['A']['B'] = $value
    so I came up with

    PHP Code:
    public function setSetting($key,$value) {
        if(
    is_array($key)) {
            foreach(
    $key as $i) {
                
    $e.="['".$i."']";
            }

            eval(
    '$this->setting'.$e.'='.$value.';');
        } else {
            
    $this->setting[$key] = $value;
        }

    which, if $key is array('A','B'), solves the problem

    However, I really don't want to be using eval() and I couldn't get me head round how to nest the array levels properly in order to build the array naturally.

    Any ideas???
    I said I didn't like ORM!!! <?php $this->model->update($this->request->resources[0])->set($this->request->getData())->getData('count'); ?>

    PDO vs mysql_* functions: Find a Migration Guide Here

    [ Xeneco - T'interweb Development ] - [ Are you a Help Vampire? ] - [ Read The manual! ] - [ W3 methods - GET, POST, etc ] - [ Web Design Hell ]
  2. #2
  3. Sarcky
    Devshed Supreme Being (6500+ posts)

    Join Date
    Oct 2006
    Location
    Pennsylvania, USA
    Posts
    10,846
    Rep Power
    6351
    PHP Code:
    class myClass {
         private 
    $setting = array(
            
    "A" => array("A" => "Leave alone""B" => "Change Me"),
            
    "B" => array("A" => "unchanged")
        );

        function 
    set($keys$value) {
            if ( !
    is_array($keys) ) {
                
    $this->setting[$keys] = $value;
            } else {    
                
    $a = &$this->setting;
                foreach ( 
    $keys AS $key ) {
                    
    //right here, check to see if $a is an array, if not, set it to an array with the key necessary.
                    
    $a = &$a[$key];
                }
                
    $a $value;
            }
        }
        function 
    printsetting() {
            return 
    print_r($this->setting,1);
        }
    }

    $class = new myClass();
    $class->set(array("A","B"), "You have been changed");
    $class->set("C""Non-array setting");
    echo 
    "<pre>" $class->printsetting() . "</pre>"
    Outputs:
    Code:
    Array
    (
        [A] => Array
            (
                [A] => Leave alone
                [B] => You have been changed
            )
    
        [B] => Array
            (
                [A] => unchanged
            )
    
        [C] => Non-array setting
    )
    -Dan

    Comments on this post

    • Northie agrees : many thanks
    Last edited by ManiacDan; November 16th, 2009 at 10:07 AM.
    HEY! YOU! Read the New User Guide and Forum Rules

    "They that can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety." -Benjamin Franklin

    "The greatest tragedy of this changing society is that people who never knew what it was like before will simply assume that this is the way things are supposed to be." -2600 Magazine, Fall 2002

    Think we're being rude? Maybe you asked a bad question or you're a Help Vampire. Trying to argue intelligently? Please read this.
  4. #3
  5. Mad Scientist
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Oct 2007
    Location
    North Yorkshire, UK
    Posts
    3,661
    Rep Power
    4123
    So how would your code work if I wanted the settings property to go to 3, 4, .... , n levels. I can see how my code would work, but not yours
    I said I didn't like ORM!!! <?php $this->model->update($this->request->resources[0])->set($this->request->getData())->getData('count'); ?>

    PDO vs mysql_* functions: Find a Migration Guide Here

    [ Xeneco - T'interweb Development ] - [ Are you a Help Vampire? ] - [ Read The manual! ] - [ W3 methods - GET, POST, etc ] - [ Web Design Hell ]
  6. #4
  7. Contributing User
    Devshed Frequenter (2500 - 2999 posts)

    Join Date
    Mar 2008
    Location
    North Carolina
    Posts
    2,674
    Rep Power
    2674
    Take a look at what I came up with (for a different problem) here. It may (or may not) help you solve yours.
  8. #5
  9. Sarcky
    Devshed Supreme Being (6500+ posts)

    Join Date
    Oct 2006
    Location
    Pennsylvania, USA
    Posts
    10,846
    Rep Power
    6351
    My code works for as many levels as you want, it continuously references the next variable in the chain.

    You could...try it.

    Here, I even added the code I said you'd need:
    PHP Code:
    class myClass 
         private 
    $setting = array( 
            
    "A" => array("A" => "Leave alone"), 
            
    "B" => array("A" => "unchanged"
        ); 

        function 
    set($keys$value) { 
            if ( !
    is_array($keys) ) { 
                
    $this->setting[$keys] = $value
            } else {     
                
    $a = &$this->setting
                foreach ( 
    $keys AS $key ) { 
                    if ( !
    is_array($a) ) $a = array($key=>array()); 
                    
    $a = &$a[$key]; 
                } 
                
    $a $value
            } 
        } 
        function 
    printsetting() { 
            return 
    print_r($this->setting,1); 
        } 


    $class = new myClass(); 
    $class->set(array("A","B""C""D"), "You have been changed!"); 
    $class->set("C""Non-array setting"); 
    echo 
    "<pre>" $class->printsetting() . "</pre>";  
    die(); 
    -Dan
    HEY! YOU! Read the New User Guide and Forum Rules

    "They that can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety." -Benjamin Franklin

    "The greatest tragedy of this changing society is that people who never knew what it was like before will simply assume that this is the way things are supposed to be." -2600 Magazine, Fall 2002

    Think we're being rude? Maybe you asked a bad question or you're a Help Vampire. Trying to argue intelligently? Please read this.
  10. #6
  11. Mad Scientist
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Oct 2007
    Location
    North Yorkshire, UK
    Posts
    3,661
    Rep Power
    4123
    Originally Posted by ManiacDan
    My code works for as many levels as you want, it continuously references the next variable in the chain.

    You could...try it.
    You're right, it does work!

    i read your original post on my phone, so couldn't really test it. I read the code and thought it was just capable of doing 1-level deep arrays.

    I have tested it now, put it in my own class and tested it and it works perfectly.

    I knew at the beginning that I was going to have to use references, but couldn't see the way forward.

    Many thanks!
    I said I didn't like ORM!!! <?php $this->model->update($this->request->resources[0])->set($this->request->getData())->getData('count'); ?>

    PDO vs mysql_* functions: Find a Migration Guide Here

    [ Xeneco - T'interweb Development ] - [ Are you a Help Vampire? ] - [ Read The manual! ] - [ W3 methods - GET, POST, etc ] - [ Web Design Hell ]
  12. #7
  13. Sarcky
    Devshed Supreme Being (6500+ posts)

    Join Date
    Oct 2006
    Location
    Pennsylvania, USA
    Posts
    10,846
    Rep Power
    6351
    Obviously, this code also creates entries that don't have the tree structure defined, you could take this original code and add:
    PHP Code:
    $class->set(array("Languages""Hello"), array("English"=>"Hello"));
    $class->set(array("Languages""Hello""French"), "Bonjour"); 
    And it will work perfectly. Note that I defined the array "wrong" in the first one, but it was still picked up properly in the second line.

    -Dan
    Last edited by ManiacDan; November 16th, 2009 at 06:44 PM.
    HEY! YOU! Read the New User Guide and Forum Rules

    "They that can give up essential liberty to obtain a little temporary safety deserve neither liberty nor safety." -Benjamin Franklin

    "The greatest tragedy of this changing society is that people who never knew what it was like before will simply assume that this is the way things are supposed to be." -2600 Magazine, Fall 2002

    Think we're being rude? Maybe you asked a bad question or you're a Help Vampire. Trying to argue intelligently? Please read this.
  14. #8
  15. Web Developer/Musician
    Devshed Regular (2000 - 2499 posts)

    Join Date
    Nov 2004
    Location
    Tennessee Mountains
    Posts
    2,408
    Rep Power
    1031
    Though it won't solve the problem all by itself, you should take note of the getter and setter capabilities built into php.

    http://www.php.net/manual/en/languag...oading.members

    It may be useful in streamlining the way you are doing it currently.
  16. #9
  17. Mad Scientist
    Devshed Expert (3500 - 3999 posts)

    Join Date
    Oct 2007
    Location
    North Yorkshire, UK
    Posts
    3,661
    Rep Power
    4123
    Originally Posted by ManiacDan
    Note that I defined the array "wrong" in the first one, but it was still picked up properly in the second line.
    Not to worry, the structure need not be defined - i need

    PHP Code:
    private $settings = array(); 
    and nothing more

    Originally Posted by Hammer65
    Though it won't solve the problem all by itself, you should take note of the getter and setter capabilities built into php.
    I was looking at overloading to begin with, but i decided I actually want callable methods, rather than trying to access non-existent properties.

    I was also looking at having a public property so I could just do

    PHP Code:
    Settings::Load()->settings['A']['B'] = 4
    (this is a singleton class I'm working with here!)

    but bespoke setter and getter methods are what i need and as far as I can see the "semantically correct" way to implement what I want

    Thanks to all
    I said I didn't like ORM!!! <?php $this->model->update($this->request->resources[0])->set($this->request->getData())->getData('count'); ?>

    PDO vs mysql_* functions: Find a Migration Guide Here

    [ Xeneco - T'interweb Development ] - [ Are you a Help Vampire? ] - [ Read The manual! ] - [ W3 methods - GET, POST, etc ] - [ Web Design Hell ]

IMN logo majestic logo threadwatch logo seochat tools logo