Hello and welcome to our community! Is this your first visit?
Register
Enjoy an ad free experience by logging in. Not a member yet? Register.
Results 1 to 14 of 14
  1. #1
    Regular Coder
    Join Date
    Jul 2005
    Posts
    131
    Thanks
    21
    Thanked 0 Times in 0 Posts

    Function to automate variables from db

    Im trying to get my head around how i would write a function to pull a load of configuration values from a database, and build variables from it too.

    Code:
    id	config_id	name		var		value
    1	1		Foo		foo		foo
    2	1		Bar		bar		bar
    What i'd like to do is create a function that looked for config_id = '1', then created an array for each entry with the designated variable name, its 'label' and the value for it.
    I then need to return the values, and be able to unpack it.

    Is this remotely possible, or am i better off just banging my head against the wall for 30min now and save myself doing that over a few days.
    Has anyone got any suggestions? how i'd go about doing that, if theres anything which would be helpful to look up which would help me with this? my coding knowledge is quite basic, i usually get by with persistence (think along the lines of monkeys & typewriters and your on the right lines ) so any pointers in the right direction for a command that might help would be a big help, as i doubt anyone will want to write something out, but pointers would be great, as would be an idea as to whether it'd be too complicated.

    Thx

    ==============================
    Update: Post #7
    AFAIK its all working fine, although if anyone can have a nosy for potential weaknesses it'd be handy.
    My level of coding is poor, so i suspect theres poor coding practice in there, but i think it should work fine.
    Last edited by PaulC2K; 08-21-2012 at 10:51 AM.

  • #2
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,994
    Thanks
    4
    Thanked 2,662 Times in 2,631 Posts
    Are you meaning so you end up with the $var = $value? I don't recommend that you do this if you can avoid it since it requires you to extract an unknown set of variables into scope. If you really need to do this, you can look at using extract(), but make sure you know what variables you are dealing with and what to do on a conflict of a variable that already exists. Its really only useful within a loop though, unless you construct an array that names the key=>value association between the var and value in the table above.

    Keeping it as an array would be no problem. Pulling that out of the SQL is trivial and as an associative would give you name, var, and value in the set of each record pulled.

  • #3
    Regular Coder
    Join Date
    Jul 2005
    Posts
    131
    Thanks
    21
    Thanked 0 Times in 0 Posts
    yeah, i'd basically be creating a function which pulled an undetermined number of variables out from thin air almost. with the name of the variable, its value, and a label all stored in the database and this function would pull them all.
    There wouldnt be an issue of duplication, each 'config' would use the same type of info, they'd just have their own values. for example, if it was for a site theme, you'd have entries for text style, colour, size, background colour, stuff like that. and there'd be 10 different variations (themes), but if i added a border colour then i wouldnt need to write it into the function, it'd adapt and generate $border_colour = '#123456'.


    Writing the initial loop aspect, i can get my head around that in time, and a dozen trial & error runs at it i suspect. Writing the return is going to be the complicated part i'd guess.

    return array ([insert an indeterminate number of variables, of indeterminate name]);
    then ive got to know the contents within the returned array, in order to 'unpack' it.

    One solution i think might work, is to take 2 runs at it. firstly to do a scan of the database, get the values of all potential variables and put that into an array of a fixed name, that can then be returned, and used to know what the 2nd attempt will be compiling, and that way i know what to unpack.

    I dunno, maybe im creating too much work for myself, i just hate the idea of deciding to implement a new element to the 'config' and then have to write that into the function, then add it to the edit page and update db code etc.
    If i could just write a script that fetched all the variables, displayed them all inside a form, and then submitted everything into the database, it'd be much easier to work with.
    I suspect the time i'd spend implementing this would be about as long as doing it the simple way and all the time spend modifying it manually, its a pain eitherway

  • #4
    Regular Coder
    Join Date
    Jul 2005
    Posts
    131
    Thanks
    21
    Thanked 0 Times in 0 Posts
    Apologies in advance for any coding practices used which are ancient

    I've bypassed the function, im just trying to pull the data and display it, and heres what i have:
    PHP Code:
        $variables = array();
        
    $sql9="SELECT * FROM `event_config` WHERE `season_id` LIKE '$season_id'";
        
    $result9 mysql_query($sql9,$db);    
        while (
    $myrow9 mysql_fetch_array($result9))
            {    
            ${
    $myrow9['config_var']}['label'] = $myrow9['config_name'];
            ${
    $myrow9['config_var']}['value'] = $myrow9['config_value'];
            
    array_push($variables$myrow9['config_var']);
            }

    foreach (
    $variables as $var)
        { 
        echo 
    " Label = ".$var['label']." | Value = ".$var['value']."<br>";
        }

    echo 
    "<br><br> Label = ".$webname['label']." | Value = ".$webname['value']."<br>"
    Im getting:
    Label = w | Value = w
    Label = s | Value = s
    Label = p | Value = p
    Label = f | Value = f
    Label = s | Value = s
    Label = d | Value = d
    Label = l | Value = l
    Label = s | Value = s
    The label is the first letter only, and the value seems to be a repeat of the label, it doesnt match the answer.

    for the last line of the script, giving it a asking for a variable i know it should create, i get the results i expect to get. What am i missing in the foreach?

  • #5
    Regular Coder
    Join Date
    Jul 2005
    Posts
    131
    Thanks
    21
    Thanked 0 Times in 0 Posts
    Got there eventually with the single letters, i was using $var['label'] instead of ${$var}['label'].

    I expected that to take me a fair number of hours, rather than about 1hr. Now it just needs to be put into a function, thats the bit i expect to struggle with though.
    I'll take a look at that tomorrow though, at least i know i can compile the data and extract it however i need, i just need to package it up into a function now.

  • #6
    Regular Coder
    Join Date
    Jul 2005
    Posts
    131
    Thanks
    21
    Thanked 0 Times in 0 Posts
    Had a quick mess, with some dummy info, and i can figure out how to write 99% of the function, and how to turn the output into what i want, however ive no idea how to write the bit passing the info through.

    ie
    return array($var1, $var2, $var3);
    & list ($var1, $var2, $var3) = function();

    Those work if i know for certain the name of the variable, and how many there are, and hard code it for them. I need something thats flexible.

    I need something that takes my list of variables its just generated, and enters all of them into the 'return' part so it turns
    return array($all_my_variables);
    into return array($var1, $var2, $var3);
    or return array($var1, $var2, $foo, $bar); etc.

    likewise i need the same for list ($all_my_variables) = function();


    I already have an array with say:
    Array ( [0] => numberOne [1] => numberTwo [2] => numberThree [3] )
    which lists all the variables it needs to pass through. I also have it as a text, ie '$numberOne, $numberTwo, $numberThree' incase i can 'paste' it into something and let it read the names of the variables from that.
    If either of those would be useful, i dont know how to use them.

    So i need to know how to write the exit for a function with an unknown number of variables, of unknown names. I suspect doing the reverse will be a similar process?
    Anyone any idea how i can do that??

    Otherwise, i think everything is done, i just dont know how the final piece of the jigsaw needs to be wrote
    Last edited by PaulC2K; 08-21-2012 at 12:22 AM.

  • #7
    Regular Coder
    Join Date
    Jul 2005
    Posts
    131
    Thanks
    21
    Thanked 0 Times in 0 Posts
    ok, think i figured it out by putting the automated arrays into a single array of a given name, that way i can pass that through.

    Its not pretty by all means, but it works

    PHP Code:
    function partThree($season_id)
        {
        require (
    $_SERVER["DOCUMENT_ROOT"]."/public/mysql_eventsdb.php");
        
    $var_master = array();

        
    $sql9="SELECT * FROM `event_config` WHERE `season_id` LIKE '$season_id'";
        
    $result9 mysql_query($sql9,$db);    
        while (
    $myrow9 mysql_fetch_array($result9))
            {
            ${
    $myrow9['config_var']}['variable'] = $myrow9['config_var'];
            ${
    $myrow9['config_var']}['label'] = $myrow9['config_name'];
            ${
    $myrow9['config_var']}['value'] = $myrow9['config_value'];
            
            
    array_push($var_master, ${$myrow9['config_var']} );    
            }

        return 
    $var_master;
        } 

    PHP Code:
    $var_master partThree($season_id);

    foreach (
    $var_master as $var)
        { 
        
    $var_name $var['variable'];

        ${
    $var_name}['variable'] = $var['variable'];
        ${
    $var_name}['label'] = $var['label'];
        ${
    $var_name}['value'] = $var['value']; 

        echo ${
    $var_name}['variable']." | ".${$var_name}['label']." | ".${$var_name}['value'] ."</br>";
        } 
    Managed to re-write it and cut a chunk out just while writing this post

    So that creates an array, with a name defined within the database, and gives it a 'label' and a value. It adds the array to a master array, which the function returns to the user.
    From there, its just breaking it down, recreating the individual variables/arrays, and echoing them to check they're correct.

    I have to admit, i expected it to take me a hell of a lot longer to wrap my head around it, and im surprised ive been able to create the function, and output the data in just 20 lines of code, i expected hundreds


    Anyone able to suggest any improvements, or highlight any problems?

  • #8
    Super Moderator
    Join Date
    Feb 2009
    Location
    England
    Posts
    539
    Thanks
    8
    Thanked 63 Times in 54 Posts
    Well, I've seen this thread twice just deleting spam, so out of decency I'll reply too

    Firstly, never, ever, ever determine variable names from a database or user input. Ever. You're going to have a problem, the worst of which will be someone hacking the script. Put it into an associative array instead: $data[$var_name]['label'] = $var['label']; Every time you do what you did up there, God kills a kitten. You now have a whole litter on your conscience.

    Secondly I'm going to explain why you got the first letter only: Strings can be accessed like an array too, a zero indexed array, $str[0] is the first character. If you access a string with $str['notanumber'], PHP thinks it's being smart and converts 'notanumber' to an int. The int value of notanumber is 0: the first character. This can also lead to seemingly weird results if your string happens to begin with a number...
    lamped.co.uk :: Design, Development & Hosting
    marcgray.co.uk :: Technical blog

  • Users who have thanked Lamped for this post:

    PaulC2K (08-21-2012)

  • #9
    Regular Coder
    Join Date
    Jul 2005
    Posts
    131
    Thanks
    21
    Thanked 0 Times in 0 Posts
    Oh im sure I have millions of litters on my conscience If i was a builder, i'd be using superglue and selotape

    Im not sure i follow the difference though to be honest, thats assuming i can understand what an associative array is first (googling it doesnt make it instantly clearer how it'd help).

    The database would hopefully hold hundreds of configuration settings, which influence how a small, but important aspect of the site, would act.
    I guess I could create a text file like an ini file, get the config from that. I could also manually update every required page to add any new options within a config that i'd add, its time consuming but not the end of the world.

    But i dont get what that advice offers tbh, its not that i disgree with it, i dont understand it.
    Currently my config data is stored in a database, and i manually request every piece of info before making use of it. I need to add a way to update all the values associated with that config, and give groups of people access to edit their groups config settings.
    Just a simple form, updating the data back to the db.

    Because i cant predict how i'll expand it, i thought it made sense to write a function to fetch all the config settings and put them in an array. That way i can pull specific values from it, and i can write a form that allows me to edit every value within that config, whether theres 2 settings or 20, I wouldnt need to lift a finger.

    I get that you say its a vulnerable method, but not what the suggestion means. Are you saying the previously posted array is vulnerable, or taking it from the database?

    In terms of the sort of content within these, they're not like php configuration or major site settings, they're visual styles, dates in which areas should be accessible, labels for the areas, they're settings which change the way that group interacts with the user, what it should display etc.

    I dont quite 'get' the advice, so thats a bit more info if that sheds light on what im doing, what should i be looking to modify, where am i vulnerable??

    Thanks for doing the thread tidy-up too, damn spambots theres been 3 in total this morning.

  • #10
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,994
    Thanks
    4
    Thanked 2,662 Times in 2,631 Posts
    lol
    Whether you use a file or a database is really quite irrelevant. The biggest problem is I don't see how you are actually using this.
    Fetching database or file information and promoting to variables I don't like. I am happy with the use of hardcoded variables and ini generated variables (to an extent). The problem without the hardcode or ini approach is you simply cannot detect and know what the variables are within the script before runtime, and this I don't like. An array is a better solution to this, but I don't know what level of reliance you currently have.

    If you are in a spot where you have already specified hardcoded variables, then you really have no alternative but to extract to a variable. This is actually a lot easier to do than what you have here, but you cannot make use of more than one key => value combo at a time, so you have an extra field you want. It looks to me that you need the var, value and label, but I don't know what all three of these represent. Another part of the problem is simply the scope.

    Since you do have the three, a better option is to look into an OO solution for this. Objects are passed by object reference in PHP5, so you can retrieve original object pointers created within functions, so you can get around a scope issue by either passing or returning. So for this, I'd write two classes, one variable and one variables to do all the work for me:
    PHP Code:
    class Variable
    {
        private 
    $lable;
        private 
    $varname;
        private 
    $value;

        public function 
    __construct($label$varname$value)
        {
            
    $this->label $label;
            
    $this->varname $varname;
            
    $this->value $value;
        }

        public function 
    getLabel()
        {
            return 
    $this->label;
        }

        public function 
    getVarname()
        {
            return 
    $this->varname;
        }

        public function 
    getValue()
        {
            return 
    $this->value;
        }
    }

    class 
    Variables implements IteratorAggregate
    {
        private 
    $ao;

        public function 
    __construct()
        {
            
    $this->ao = new ArrayObject();
        }

        public function 
    addVariable(Variable $v)
        {
            if (isset(
    $this->ao[$v->getVarname()]))
            {
                throw new 
    RuntimeException("Variable is already in list");
            }
            
    $this->ao[$v->getVarname()] = $v;
        }

        public function 
    getIterator()
        {
            return 
    $this->ao->getIterator();
        }

        public function 
    getVariableByName($sVar)
        {
            return isset(
    $this->ao[$sVar]) ? $this->ao[$sVar] : null;
        }

        public function 
    getVariableValueByName($sVar)
        {
            return isset(
    $this->ao[$sVar]) ? $this->ao[$sVar]->getValue() : null;
        }

    Just something simple; the variables class in particular would really need a rewrite, and observers should be used in case the Variable class is given the ability to change the varname so it can trigger an update to the list and toss if it's given a duplicate.
    The nice part is the usage:
    PHP Code:
    function getSomeData()
    {
        
    $variables = new Variables();
        
    $sQry 'SELECT label, varname, value FROM databasetable WHERE condition';
        if (
    $qry mysql_query($sQry))
        {
            while (
    $row mysql_fetch_assoc($qry))
            {
                
    $variables->addVariable(new Variable($row['label'], $row['varname'], $row['value']));
            }
        }
        return 
    $variables;
    }

    $variables getSomeData();

    printf("Variable value for 'bar' is %s" PHP_EOL$variables->getVariableValueByName("bar")); 
    A procedural approach to the above is to simply make use of a static array, and handle it preferably by returned reference and several functions to deal with it. It effectively ends up about the same but is called differently.
    PHP Code:
    function &populateData()
    {
        static 
    $a;
        if (empty(
    $a))
        {
            
    // you query here.  I'll just write it hardcoded for this example.
            // the query will need to create the offsets as appopriately
            
    $a = array();
            
    $_tmpArray = array(
                array(
    'Fou''fou''fou'), // just a bit of humor :)
                
    array('Bar''bar''bar')
            );
            foreach (
    $_tmpArray AS $row// This is the simulated query
            
    {
                list(
    $label$varname$value) = $row;
                
    $a[$varname] = array('label' => $label'value' => $value);
            }
        }

        return 
    $a;
    }

    function 
    getVariableByName($varname)
    {
        
    $a populateData();
        return 
    $a[$varname];
    }

    function 
    getVariableValueByName($varname)
    {
        
    $a populateData();
        return isset(
    $a[$varname]['value']) ? $a[$varname]['value'] : null;
    }

    printf("Variable 'fou': %s" PHP_EOLprint_r(getVariableByName("fou"), true));
    printf("Variable value for 'bar': %s" PHP_EOLgetVariableValueByName("bar"));

    // And the purpose of the by ref
    $a = &populateData();
    $a['anewvar'] = array('label' => 'A New Var''value' => 'anewvar');

    foreach (
    $a AS $var => $info)
    {
        
    printf("Variable %s is given info of %s" PHP_EOL$varprint_r($infotrue));
    }

    printf("Variable 'anewvar' value: %s" PHP_EOLgetVariableValueByName("anewvar")); 
    For an example.

    And finally, if you really must have a variable itself given the value of the varname from the database, simply inject it into the $GLOBALS. I don't recommend this since it is tougher to track:
    PHP Code:
    function getSomeData()
    {
        
    // your query here
        
    while ($row mysql_fetch_assoc($qry))
        {
            if (!isset(
    $GLOBALS[$row['varname']])
            {
                
    $GLOBALS[$row['varname']] = array('label' => $row['label'], 'value' => $row['value']);
            }
        }

    And then after the call, a global will exist with the name given by $row['varname']. I had to make it an array still since I haven't a clue the relationship between varname, label and value.

    Hope that helps.

  • Users who have thanked Fou-Lu for this post:

    PaulC2K (08-21-2012)

  • #11
    Regular Coder
    Join Date
    Jul 2005
    Posts
    131
    Thanks
    21
    Thanked 0 Times in 0 Posts
    i've no idea what im doing, but maybe im on the right lines

    The mass slaughtering of innocent kittens is due to my method of introducing the values into the code, by using $var_name['label'] rather than anything to do with pulling from databases or the actual practice of generating these variables, its the naming??

    I dont think the function would be a problem, but then WTF do i know, so i updated that too (i suspect i dont need to, seeing as they're never really 'live' within the site?) and i've also copied the 'associative array' example.
    Am i remotely close, or miles off as usual??

    PHP Code:
    function partFive($season_id)
        {
        require (
    $_SERVER["DOCUMENT_ROOT"]."/public/mysql_eventsdb.php");
        
    $var_master = array();

        
    $sql9="SELECT * FROM `event_config` WHERE `season_id` LIKE '$season_id'";
        
    $result9 mysql_query($sql9,$db);    
        while (
    $myrow9 mysql_fetch_array($result9))
            {
            echo 
    "** ".$myrow9['config_var']." ** <br>";    
            
    $data[$myrow9['config_var']]['variable'] = $myrow9['config_var'];
            
    $data[$myrow9['config_var']]['label'] = $myrow9['config_name'];
            
    $data[$myrow9['config_var']]['value'] = $myrow9['config_value'];
                    
            
    array_push($var_master$data[$myrow9['config_var']] );    
            }

        return 
    $var_master;
        } 

    PHP Code:
    foreach ($var_master as $var)
        { 
        
    $var_name $var['variable'];
        
    $data[$var_name]['variable'] = $var['variable'];
        
    $data[$var_name]['label'] = $var['label'];
        
    $data[$var_name]['value'] = $var['value'];

        echo 
    $data[$var_name]['variable'] ." | "$data[$var_name]['label'] ." | "$data[$var_name]['value'] ."</br>";    } 
    Any better?

  • #12
    Regular Coder
    Join Date
    Jul 2005
    Posts
    131
    Thanks
    21
    Thanked 0 Times in 0 Posts
    Fou-Lu -
    I think my poor brain melted before i even got to the first example

    They're just various pieces of information which influence whats displayed in a specific area of the site.
    The table consists of:
    id, config_id, variable name, label for it, the value.

    Code:
    id	c_id	var		label			value
    1	1	name		Event Name		CodingForums Event
    2	1	signup		Signup Type		public
    3	1	open		Open Date		2012/01/01
    4	1	close		Close Date		2013/01/01
    
    5	2	name		Event Name		Another Event
    6	2	signup		Signup Type		invitation
    7	2	open		Open Date		2012/09/01
    8	2	close		Close Date		2012/10/01
    At the moment in my database, every 'config' has 7 pieces of info, compared to the 4 above, every config should consist of the same 7 pieces (or however many i implement), same [var] & [label] but with their own [value]. If the site gets finished, there would be hundreds of configurations.


    With the script, i want to be able to fetch all the configuration settings for a particular event (config_id) within an array.

    My coding ability is limited at best, i absorb next to nothing i learn as im coding (goes for a lot of things unfortunately) and the terminology goes whoosh over my head a lot of the time so its a pain trying to explain what i want, cos i dont know the correct way to explain it, and often what i need to do. correct coding practice goes out the window typically, not cos i dont care, but cos i wouldnt know where to begin and most of my coding is spelt out in the simplest of terms (so i can understand it, and cos i dont know the efficient or best methods).

    What i wanted to do was create a private page, a form with the config settings for that 'event'. name, signup, open & close. I could write the page, put 4 text boxes, the submit to db code etc, thats fine. But if i add a new entry to that config, say background_colour, 9 1 colour Background Colour #ff0000 i'd have to modify the form.

    With this method, i dont.
    I'd have an array with every associated value for that config -> name, signup, open, close & colour.
    I can create a loop which displays a textbox for every setting, then submit each value into the database when prompted.
    i'd just request $data[colour]['value'] and get my answer.


    It just creates a dynamic form for me, there may be far better ways of doing it, but im a n00b, i've been coding in my spare time for around 10 years and this is pretty much my level. I wont create anything special, and it'll be anything but efficient, i just hope to implement the functionality i want to give the sites.
    The project im working on at the moment is way over my head, and ive already put around 1500hrs into it over a number of years, and about 5 people have seen it (its not live, thankfully ). I get by with determination, passion, google, an absolute ton of trial & error, and as a last resort i'll post on here for assistance (cos i'd rather find the answer myself).

    Maybe the application is pointless, i dunno, i just thought it'd save me time if the form was self-generating, and i could leave it alone while still adding other settings to it and it adapting.
    The childish manner in which its wrote, thats just where im at, i dont know any better, and attempts to try and learn from reading almost nothing is absorbed, and learning from doing isnt all that much more successful. Its pretty much what i have to do to make it work, its that or nothing really.

  • #13
    God Emperor Fou-Lu's Avatar
    Join Date
    Sep 2002
    Location
    Saskatoon, Saskatchewan
    Posts
    16,994
    Thanks
    4
    Thanked 2,662 Times in 2,631 Posts
    Can you have multiple c_id available at the same time? If not, any of the examples I have would work fine (the first one though the oop Variable class has the wrong property, it should be private $label not private $lable).
    Since I made variables iterable, then it can be fetched in a foreach:
    PHP Code:
    foreach ($variables AS $variable)
    {
        
    printf('<label for="%s">%s</label><input type="text" name="%s" id="%s" value="%s" />' PHP_EOL'id_' $variable->getVarname(), $variable->getLabel(), $variable->getVarname(), 'id_' $variable->getVarname(), $variable->getValue());


  • Users who have thanked Fou-Lu for this post:

    PaulC2K (08-21-2012)

  • #14
    Regular Coder
    Join Date
    Jul 2005
    Posts
    131
    Thanks
    21
    Thanked 0 Times in 0 Posts
    No, only 1 c_id is active.

    In the code ive posted, ive got the table 'event_config' and im using '$season_id' (same as 'c_id' in example) to pull all the settings relating to that season event.

    There would be hundreds of events run over time, and the config table would hold a load of individual settings relevant to how it operates.
    The structure of the events are held elsewhere, but the basic settings would be held here. Every event would have the same pieces of information it'd need, but they'd have their own values - each one needs a start date, but they'd have the same variable name and the label is just for explaining what its for really.

    tbh, as much as i appreciate the code you've gone to the trouble of providing for me, i cant even read it to understand what its doing. its way beyond my understanding. I cant rely upon something that makes no sense to me if you know what i mean sorry

    Is what ive wrote earlier still bad practice? it seems to be doing the job i need from it, but if its still got a significant vulnerability to it then i'll either fix it (if i can) or give up and go back to hard coded pages & updating it as and when needed.


  •  

    Posting Permissions

    • You may not post new threads
    • You may not post replies
    • You may not post attachments
    • You may not edit your posts
    •