php reading custom config file and allowing edits via html form - php

I have a "config" file that lists some configs of another program, and I have a need for my PHP backend application to be able to read and write to this file, hopefully via html forms.
The config file is in the format:
something: 4
something_else: false
then_this: 68000
and_then_this: false
finally_this: true
There is one config parameter per line, and each config parameter is in the format: parameter: value. Ideally I would need the function to read all the parameters and values in this file, stuff them in an array and then iterate through them and allow them to be edited via forms:
$configArray = array(); // The config array would contain the key/value pairs of the parameter: value mentioned above
<form action="edit.php" method="post">
<?php foreach($configArray as $p=>$v) { ?>
<strong><?php echo $p; ?></strong> <input type="text" name="<?php echo $p; ?>" value="<?php echo $v; ?>" />
<?php } ?>
<input type="submit">Save changes!</input>
</form>
Using the above example of how I wish the array to be laid out, I would expect to use var_dump($configArray); and produce the following results:
array(5) {
["something"]=>
int(4)
["something_else"]=>
bool(false)
["then_this"]=>
int(68000)
["and_then_this"]=>
bool(false)
["finally_this"]=>
bool(true)
}
This would produce a list of forms from the config file parameter: value and allow the user to edit them and then save them back to the same file.
Is something like this even possible with PHP?

This might help you. Please change the path and name of the config file instead of "config.txt" in the example below:
<?php
error_reporting(E_ALL);
ini_set('display_errors', 1);
ini_set('log_errors', 0);
// Read the file content
$content = file('config.txt', FILE_SKIP_EMPTY_LINES);
if ( $content === FALSE ) {
die('Could not read the config file.');
}
// Parse content to create array
$configArray = array();
foreach($content as $config_line) {
list($key, $val) = explode(':', $config_line);
// Remove white space
$val = trim($val);
// Check type of $val
switch(strtolower($val)) {
case 'true':
case 'false':
$type = 'boolean';
break;
case (preg_match('/^[0-9]/', $val) ? true : false) :
$type = 'integer';
break;
default:
$type = 'string';
break;
}
// And set it dynamically
settype($val, $type);
$configArray[$key] = $val;
}
var_dump($configArray);
?>

Related

Reading/Writing boolean values to INI file in PHP

First, forgive me if this is an overly pedantic question. I have searched trying to find answers but perhaps I'm using the wrong search terms.
Trying to use an INI file for a simple PHP application, where there is an admin page to allow application options to be easily changed. I'm able to read in the ini file with no issue, problem I'm coming across is on the write - if any boolean values are false, they won't get put into the _POST and as such don't get written back into the ini file. Here's my sample:
settings.ini file:
[Site options]
bRequireLegal['Require NDA before badge print'] = true ;
bCollectVehicleInfo['Collect vehicle information'] = false;
bShowAdditionalMessageBeforeBadgePrint['Show badge printing message'] = true;
[Company info]
companyname['Company Name'] = 'The Company, Inc.' ;
Code to read in the ini file (settings.php):
$filepath = 'settings.ini'; //location of settings file
$settings = parse_ini_file($filepath, true, $scanner_mode = INI_SCANNER_TYPED);
//pull everything in ini file in as variable
foreach($settings as $section=>$options){
foreach($options as $option=>$values){
foreach($values as $descriptor=>$value){
if(is_bool($value) === true) {
${htmlspecialchars($option)} = +$value;
}
else ${htmlspecialchars($option)} = $value;
}
}
}
And finally, the options setting page:
<?php
include 'settings.php';
//after the form submit
if($_POST){
$data = $_POST;
update_ini_file($data, $filepath);
}
function update_ini_file($data, $filepath) {
$content = "";
//parse the ini file to get the sections
foreach($data as $section=>$options){
//append the section
$content .= "[".$section."]\r\n";
//append the values
foreach($options as $option=>$values){
$content .= $option;
foreach($values as $descriptor=>$value){
$content .= "['".$descriptor."'] = '".$value."';\r\n";
}
}
$content .= "\r\n";
}
if (!$handle = fopen($filepath, 'w')) {
return false;
}
$success = fwrite($handle, $content);
fclose($handle);
return $success;
}
?>
<html>
<body>
<?php
?>
<div class="container-fluid">
<form action="" method="post">
<?php
foreach($settings as $section=>$options){
echo "<h3>$section</h3>";
//keep the section as hidden text so we can update once the form submitted
echo "<input type='hidden' value='$section' name='$section' />";
//print all other values as input fields, so can edit.
foreach($options as $option=>$values){
foreach($values as $descriptor=>$value){
if(is_bool($value) === true) {
echo "<p>".$descriptor.": <input type='checkbox' name='{$section}[$option][$descriptor]' ".(($value===true)?" checked":"")." /></p>";
} else
echo "<p>".$descriptor.": <input type='text' name='{$section}[$option][$descriptor]' value='$value' />"."</p>";
}
}
echo "<br>";
}
?>
<input type="submit" value="Update INI" />
</form>
</div>
</body>
</html>
Any help would be greatly appreciated!
In your update_ini_file() function, replace this:
$content .= "['".$descriptor."'] = '".$value."';\r\n";
with
$content .= "['".$descriptor."'] = '".($value ? 'true' : 'false')."';\r\n";
This will cause it to write the strings 'true' and 'false' instead of literal Boolean values. See How to Convert Boolean to String
Edit to add:
I think you're generating your checkboxes incorrectly:
<input type='checkbox' name='{$section}[$option][$descriptor]' ".(($value===true)?" checked":"")." />
This will cause the 'true' boxes to be checked, but they will still lack a value (and thus will not be transmitted to the server when the form is submitted). You should change that code to:
<input type='checkbox' name='{$section}[$option][$descriptor]' value='1'".(($value===true)?" checked":"")." />
In other words, all checkboxes should have a value of '1', but the way the browser works, only those which are checked will be submitted.
Edit to add:
Checkboxes that are not checked will not get submitted. That explains why you are not seeing any output for values that are 'false': they simply don't get submitted. When you loop through $data (which comes from $_POST), it is missing those unchecked (and thus 'false') checkboxes.
Using a solution found here: POST unchecked HTML checkboxes
Change this:
echo "<p>".$descriptor.": <input type='checkbox' name='{$section}[$option][$descriptor]' ".(($value===true)?" checked":"")." /></p>";
to this, which includes a hidden field that has the value '0', which will get submitted even if the corresponding checkbox is unchecked:
echo "<p>".$descriptor.": <input type='hidden' name='{$section}[$option][$descriptor]' value='0'><input type='checkbox' name='{$section}[$option][$descriptor]' ".(($value===true)?" checked":"")." /></p>";
However, this has its own set of potential problems, specifically when a checkbox is checked, you will send two identically named fields: one with a '0' value and the other with a '1' value. This is explained in the link above, and is left as an exercise for you to solve (or ask for further details on) if my answer doesn't work.

Open php file, change value for one variable, save

I am trying to modify the value of a variable $denumire produs=' '; from a php file _inc.config.php through a script by this code with form from file index.php and i have some errors.
The new value of the variable will become value entered from the keyboard via the form.
Anyone can help me, please?
<?php
if (isset($_POST['modify'])) {
$str_continut_post = $_POST['modify'];
if (strlen($_POST['search']) > 0 || 1==1) {
$fisier = "ask003/inc/_inc.config.php";
$fisier = fopen($fisier,"w") or die("Unable to open file!");
while(! feof($fisier)) {
$contents = file_get_contents($fisier);
$contents = str_replace("$denumire_produs =' ';", "$denumire_produs ='$str_continut_post';", $contents);
file_put_contents($fisier, $contents);
echo $contents;
}
fclose($fisier);
die("tests");
}
}
?>
<form method="POST" action="index.php" >
<label>Modifica denumire baza de date: </label>
<input type="text" name="den">
<button type="submit" name="modify"> <center>Modifica</center></button>
</div></div>
</form>
This is an XY problem (http://xyproblem.info/).
Instead of having some sort of system that starts rewriting its own files, why not have the file with the variable you want to change load a json config file?
{
"name": "Bob",
"job": "Tea Boy"
}
Then in the script:
$json = file_get_contents('/path/to/config.json');
$config = json_decode($json, true);
$name = $config['name'];
Changing the values in the config is as simple as encoding an array and putting the json into the file.
$config['denumireProdu'] = 'something';
$json = json_encode($config);
file_put_contents('/path/to/config.json', $json);
This is far saner than getting PHP to rewrite itself!
Docs for those commands:
http://php.net/manual/en/function.json-decode.php
http://php.net/manual/en/function.json-encode.php
http://php.net/manual/en/function.file-get-contents.php
http://php.net/manual/en/function.file-put-contents.php

PHP - fwrite PHP Data With Set Variables

I am trying to figure out how to fwrite into a .php file with variables given through $_POST, or $_GET, supplied by the user to set variables and such. So, how would I go about getting the below code to work so that instead of fwriting the code, insert a $_GET variable for example, or in the below description, being $derp.
<?php
$derp = "working!";
$something = '<?php echo "Well Thats {$derp}' ?>';
$file = fopen("worked.php","w");
if (fwrite($file,$something) > 0) {
echo "Fwrite Successful!";
}
fclose($file);
?>
Although this use case looks very weird the following should work:
$data = array('<?php');
foreach ($_REQUEST as $key => $value) {
$data[] = "\$$key = \"$value\";";
}
$data[] = '?>';
$data = join("\n", $data);
file_put_contents('/path/to/file.php', $data);
Beware: This code imposes several security risks.
WTF is going on here?
The above code iterates through all array elements of $_GET and $_POST, combined.
By that it creates an array of lines to be written to a file.
This array will then be join()ed into a string by using the NEWLINE ascii character as the glue.
Assuming this script is called with the following query string:
?foo=bar&bar=baz
The file /path/to/file.php will then contain (file_put_contents):
<?php
$foo = "bar";
$bar = "baz";
?>
The example above does not support nested query parameters like foo[bar]=baz.

Merge 2 php scripts

I need some help with some php scripting. I wrote a script that parses an xml and reports the error lines in a txt file.
Code is something like this.
<?php
function print_array($aArray)
{
echo '<pre>';
print_r($aArray);
echo '</pre>';
}
libxml_use_internal_errors(true);
$doc = new DOMDocument('1.0', 'utf-8');
$xml = file_get_contents('file.xml');
$doc->loadXML($xml);
$errors = libxml_get_errors();
print_array($errors);
$lines = file('file.xml');
$output = fopen('errors.txt', 'w');
$distinctErrors = array();
foreach ($errors as $error)
{
if (!array_key_exists($error->line, $distinctErrors))
{
$distinctErrors[$error->line] = $error->message;
fwrite($output, "Error on line #{$error->line} {$lines[$error->line-1]}\n");
}
}
fclose($output);
?>
The print array is only to see the errors, its only optional.
Now my employer found a piece of code on the net
<?php
// test if the form has been submitted
if(isset($_POST['SubmitCheck'])) {
// The form has been submited
// Check the values!
$directory = $_POST['Path'];
if ( ! is_dir($directory)) {
exit('Invalid diretory path');
}
else
{
echo "The dir is: $directory". '<br />';
chdir($directory);
foreach (glob("*.xml") as $filename) {
echo $filename."<br />";
}
}
}
else {
// The form has not been posted
// Show the form
?>
<form id="Form1" action="<?php echo $_SERVER['PHP_SELF']; ?>" method="post">
Path: <input type="text" name="Path"><br>
<input type="hidden" name="SubmitCheck" value="sent">
<input type="Submit" name="Form1_Submit" value="Path">
</form>
<?php
}
?>
That basically finds all xmls in a given directory and told me to combine the 2 scripts.
That i give the input directory, and the script should run on all xmls in that directory and give reports in txt files.
And i don't know how to do that, i'm a beginner in PHP took me about 2-3 days to write the simplest script. Can someone help me with this problem?
Thanks
Make a function aout of your code and replace all 'file.xml' to a parameter e.g. $filename.
In the second script where the "echo $filename" is located, call your function.

Dropdown list with New folder option in PHP

I have this script that gets all the sub-directories and puts them into a dropdown list.
I have an option "New folder" to create a new folder by gathering the folder name - in this case, it's numbers like 995 - and discount it by one to create a dir called 994
<form action="index.php" method="post">
<select name="folderchoose" id="folderchoose" onchange="this.form.submit();">
<?php
$base = basename("$items[1]", ".php").PHP_EOL;
$newbase = $base -1;
if($_POST['folderchoose']==0){ mkdir("../albums/$newbase", 0700); }
$items = glob("../albums/*", GLOB_ONLYDIR);
natsort($items);
{?><option>select:</option><?
foreach($items as $item)
{
?> <option value="1"><? echo "$item\n "; ?></option><?
} ?> <option value="0" >New folder</option> <?
}
?>
</select>
</form>
Directory:<?php echo $_POST[folderchoose] ?><br />
<?php $base = basename("$items[1]", ".php").PHP_EOL;
$newbase = $base -1;
echo $newbase ?>
Two things aren't working properly: the mkdir function doesn't get the $newbase and create a directory called dir(??) automatically even if I'm not choosing 'New Folder'.
I have a couple of hints for you to improve your code. I do not fully understand your problem but this might help.
If you want to list a directory with all of its sub directories you should do something like this
function list_directory( $dirname ) {
foreach file in directory
if(is_dir($dirname)){
list_directory($dirname)
}
if(is_File($dirname)){
echo $dirname;
}
}
}
This is not usable code but a genral idea for you to work with.
If strange things start happening try doing this
var_dump( $var ); // The variable your are suspecting in your case $newbase
You need to change if($_POST['folderchoose']==0) to something else because 0 mean "null" and therefore the if statement is true and it will be executed.
or... Use isset() to make sure the form really get submitted, for example
if (isset($_POST['folderchoose'])) {
if ($_POST['folderchoose'] == 0) {
//do mkdir or something

Categories