Can anyone help with this PHP please?

Can anyone help with this PHP please?

Author
Discussion

TonyRPH

Original Poster:

12,972 posts

168 months

Thursday 26th March 2015
quotequote all
I am trying to read config variables form a database.

I have a table called 'mytable' like this:

id option_name option_variable
1 foldername /home/folder
2 sitename mysite
3 email example@example.com
4 tagline stuff



I want to be able to read these back and assign variables to them.

e.g.

$foldername=$row['foldername'];
$sitename=$row['sitename'];
$email=$row['email'];
$tagline=$row['tagline'];


My php looks like this:


SELECT id, option_name, option_value FROM my_table;
$result = mysql_query($query) or die("Couldn't execute query");
$count = 1 + $s ;
while ($row=mysql_fetch_array($result)) {
$option_name=$row["1"];
$option_value=$row["2"];
echo $option_name, " ---- ", $option_value, "<br />";



Now although this yields results like:
foldername ---- /home/folder
sitename ---- mysite

This is not quite what I want.

I want to be able to assign each pair as a $variable=variablename

How can I do this?

TIA.



wombleh

1,790 posts

122 months

Thursday 26th March 2015
quotequote all
I think double dollars will do that:

So change it to:
SELECT id, option_name, option_value FROM my_table;
$result = mysql_query($query) or die("Couldn't execute query");
$count = 1 + $s ;
while ($row=mysql_fetch_array($result)) {
$$row[0] = $row[1]
}


PHP manual page link

TonyRPH

Original Poster:

12,972 posts

168 months

Thursday 26th March 2015
quotequote all
Thanks, I got somewhere but I think I'm in over my head.

This table contains (or at least will contain!) config parameters for a site.

But despite getting everything displaying correctly in a web page with echo statements, once I tried converting the output to usable variables, I hit a brick wall.

The site works when loading variables from a file using an include statement - so I know that part is correct.

I think I need to go and and find out how data is read from a file and used as variables, vs. reading data from a db and using that as variables.


eltawater

3,114 posts

179 months

Thursday 26th March 2015
quotequote all
Any reason why you want these initialised into variables in their own right?

It often makes more sense to keep these sort of global load once read many variables in one array e.g $siteconfig and then reference the values by their key e.g. $siteconfig["folder name"].

That way it's less likely that someone will override your variable value in a later include file (as they also think that "email" is a good name for a variable ) and it also enables you to iterate your way through all of the elements, count them, check them for empty values rather than having to track what they're all named as.

TonyRPH

Original Poster:

12,972 posts

168 months

Thursday 26th March 2015
quotequote all
There's no reason - I'm just trying to emulate loading the configuration parameters for the site from a database instead of a config file.

I would actually want these variables to be global.

ETA: After giving it some thought, I think I need to use a $_POST statement to make the variables available - however I'm not sure on this!

Edited by TonyRPH on Thursday 26th March 22:26

wombleh

1,790 posts

122 months

Friday 27th March 2015
quotequote all
TonyRPH said:
ETA: After giving it some thought, I think I need to use a $_POST statement to make the variables available - however I'm not sure on this!
I've not kept up with the past few iterations of PHP, but previously if you wanted them global you would put them into the $GLOBALS array. Or before that all variables were global anyway but that caused much gnashing of teeth!

Personally I use constants loaded from a text file for configuration settings with the define setting. They don't need to change and it means they can't be altered if there are any holes/bugs in the code.

The problem with putting config into the database is that the means of connecting to the database should be part of the configuration, e.g. if you move it onto a different web host and the DB changes. You'd end up with config spread around different places and IMO it's better to have it in one place with a standard method of accessing it.

TonyRPH

Original Poster:

12,972 posts

168 months

Friday 27th March 2015
quotequote all
wombleh said:
<snip>
Personally I use constants loaded from a text file for configuration settings with the define setting. They don't need to change and it means they can't be altered if there are any holes/bugs in the code.
This is what I do at the moment, I just thought it would be nice to have some key editable variables (sitename, meta keywords etc.) stored in a db for easy editing by the end user.

wombleh said:
The problem with putting config into the database is that the means of connecting to the database should be part of the configuration, e.g. if you move it onto a different web host and the DB changes. You'd end up with config spread around different places and IMO it's better to have it in one place with a standard method of accessing it.
I had planned to leave the DB config in a text file, as this would generally be a one off configuration (unless the host changes of course).



droopsnoot

11,934 posts

242 months

Friday 27th March 2015
quotequote all
I can't see why you'd involve $_POST here - that's normally reserved for form data that comes to your PHP page as the result of a html form being submitted.

The double-$ should work OK, but that takes away from making it easily modifiable (which is why I assume you want to arrange the table this way) because when you add another option name and variable, you'll have to modify the code to deal with it. Another way is to use an indexed array and use the option name as the index:

$options = array();
... query
... while loop (I forget the syntax and can't see it while posting reply)
{
$options[$row['option_name']] = $row['option_variable'];
}

That should give you an array that you can access quite easily using a foreach() loop, and will deal with extra options being added.

foreach($options as $optkey => $optvar) {
echo '<tr><td>' . $optkey . '</td><td>' . $optvar . '</td></tr>';
}

You should also look at moving either to mysqli or PDO to access the database - if you're hosting this on a commercial server (or planning to), the old-style mysql calls are deprecated and will stop being supported at some point.

(Note that I'm learning PHP, so there may be better solutions).

Edited by droopsnoot on Friday 27th March 11:45

TonyRPH

Original Poster:

12,972 posts

168 months

Friday 27th March 2015
quotequote all
droopsnoot said:
<snip>

$options = array();
... query
... while loop (I forget the syntax and can't see it while posting reply)
{
$options[$row['option_name']] = $row['option_variable'];
}

That should give you an array that you can access quite easily using a foreach() loop, and will deal with extra options being added.

foreach($options as $optkey => $optvar) {
echo '<tr><td>' . $optkey . '</td><td>' . $optvar . '</td></tr>';
}

<snip>
Thanks that works (in that it displays the expected output) - however the output is not available as individual variables (even in my test page that I run this from).

Using various methods I do seem to get the output displayed in a web page (that seems to be the easy part!!) but storing the query result in variables appears to be my Achilles heel right now.



Durzel

12,267 posts

168 months

Friday 27th March 2015
quotequote all
The way you're doing it seems quite strange.

It seems like you're going about it as if your program wouldn't necessarily know the contents (or the names) of the variables at runtime, but it doesn't seem like it would be that dynamic to need that sort of abstraction. To be honest if you're asking this sort of question I'm almost certain it doesn't need this level of complexity (no offence intended). What you're seemingly trying to is what programs do when they don't know what data they're going to find, or what format it is, etc. Again, for straight "site settings" with known variables you don't need anything like this level of abstraction.

As has been said already you might as well just read these variables into define() constants at run time. You could also use session variables with the downside that if you changed any of the settings they wouldn't change in that session without you overwriting the new data. Some might argue it's a waste to run a query each time a page is loaded, but it's a pretty low overhead query frankly, and if your database is dead most sites will pretty much cease to function anyway.

Configuration text files is another option, as said above, with the caveat that you need to be careful about what can read this file, and where it is stored, etc.

Edited by Durzel on Friday 27th March 13:24

droopsnoot

11,934 posts

242 months

Friday 27th March 2015
quotequote all
TonyRPH said:
Thanks that works (in that it displays the expected output) - however the output is not available as individual variables (even in my test page that I run this from).

Using various methods I do seem to get the output displayed in a web page (that seems to be the easy part!!) but storing the query result in variables appears to be my Achilles heel right now.
Well, they are in separate variables, but as part of an array, not individually-named variables. So if you var_dump($options) outside of the foreach() loop you'll see something like:

$options['foldername'] = '/fred/bill'
$options['sitename'] = 'My test site'
and so on

and then you can use those in your html form and allow them to be edited and so on. Within the foreach loop they're accessible as $optkey and $optvar but that's just to make it easy to get to each of them.

But the point about not hard coding is true. If you hard-code the results into individual variables using the $$ contruction, you're going to need to know what each of those variables are when it comes to dealing with them later.

TonyRPH

Original Poster:

12,972 posts

168 months

Friday 27th March 2015
quotequote all
I already tried var_dump($options); and I get this:

["$galdir="]=> string(10) "galleries/"
["$thumbnail_size="]=> string(3) "150"
["$intermediate_size="]=> string(3) "800"
["$fulldir="]=> string(10) "fullsized/"

I have no idea why I'm seeing the "=> string.." part.

ETA: You're dealing with a hobbyist here (probably not the best thing for me to be doing - writing stuff like this) but I am trying to learn more about it.

Got it working at last.

Thanks for the help all.



Edited by TonyRPH on Friday 27th March 15:22

eltawater

3,114 posts

179 months

Friday 27th March 2015
quotequote all
The "String" part is trying to indicate what PHP believes is the type of variable value that is being stored in that given variable. Useful in case you try to mathematically add one variable value to another, scratch your head why, only to discover you're trying to add the integer 5 and string"fullfolder" together (which wouldn't make sense).

Implicit type casting is useful for beginners but can be quite dangerous under certain circumstances - you should always be validating the type, value, length etc of a variable before making use of it to avoid risks of buffer overflows, sql injections attacks etc.

TonyRPH

Original Poster:

12,972 posts

168 months

Friday 27th March 2015
quotequote all
I have been reading up on sanitising variables etc. (from memory htmlentity? springs to mind).

Also looking at migrating to mysqli as previously suggested.


wombleh

1,790 posts

122 months

Friday 27th March 2015
quotequote all
Have a look at htmlentites, mysqli_escape_string and regular expressions with preg_match for sanitising data. The attacks you're looking to prevent with those are XSS (cross site scripting) and SQL injection, worth having a read of some articles on how those work so you can see what you're trying to stop. May well be better ways of doing this now as I'm a few years out of date.

Be very careful with directory/file paths as that could be abused to browse the file system on the webserver.

-DeaDLocK-

3,367 posts

251 months

Friday 27th March 2015
quotequote all
I'm not exactly clear what you're trying to achieve, but if I'm right, this will do the trick:

${$option_name}=$option_value;

This is not necessarily best practice, but it solves the problem (again, assuming I'm reading you right!).

Edit: Here's all the code you need from database lookup through to variable creation:

$result=mysql_query("SELECT option_name,option_variable FROM my_table");
while($row=mysql_fetch_assoc($result)){
${$row['option_name']}=$row['option_variable'];
}

Edited by -DeaDLocK- on Friday 27th March 18:12

droopsnoot

11,934 posts

242 months

Friday 27th March 2015
quotequote all
If you have a look at prepared statements, it will do a lot of the protection work for you. You should still validate everything you take from a user input, of course, but escaping and quotes and so on are easier. I use PDO, so maybe not quite the same as mysqli.