Reading/Writing boolean values to INI file in PHP - 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.

Related

PHP: "Submit" box

I am fairly new to PHP and am having trouble with an assignment. The assignment is to create a simple address book in PHP, and i would like my address book to display all addresses that are in it along with a submission box at the bottom to add more addresses. Currently, I can get the addresses to display, but the submission box gives me an error ") Notice: Undefined variable: addres_add in C:\wamp64\www\address_tmp\address.php on line 18"
This is my code thus far, I snagged the submission box code from another answer here on StackOverflow, but I don't know how to modify it to fit my needs.
<?php
//Open address book file and print to user
$fh = fopen("address_book.txt", "r+");
echo file_get_contents("address_book.txt");
//Perfom submit function
if(isset($_POST['Submit']))
fseek($fh, 0, SEEK_END);
fwrite($fh, "$addres_add") or die("Could not write to file");
fclose($fh);
print("Address added successfully. Updated book:<br /><br />");
echo file_get_contents("address_book.txt");
{
$var = $_POST['any_name'];
}
?>
<?php
//HTML for submission box?>
<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="POST">
<input type="text" name="any_name">
<input type="submit" name="submit">
</form>
<p>
You never assigned the variable from the form input. You need:
$addres_add = $_POST['any_name'];
fwrite($fh, "$addres_add") or die("Could not write to file");
Also, if you're just adding to the file, you should open it in "a" mode, not "r+". Then you don't need to seek to the end, that happens automatically.
You probably should put a newline between each record of the file, so it should be:
fwrite($fh, "$addres_add\n") or die("Could not write to file");
Otherwise, all the addresses will be on the same line.
Here is a simpler version of your program.
<?php
$file_path ="address_book.txt";
// Extract the file contents as a string
$file_contents = file_get_contents($file_path);
if ($file_contents) // Check if the file opened correctly
echo($file_contents . " \n"); // Echo contents (added newline for readability)
else
echo("Error opening file. \n");
// Make sure both form fields are set
if(isset($_POST['submit']) && isset($_POST['any_name']))
{
// Append the new name (used the newline character to make it more readable)
$file_contents .= $_POST["any_name"] ."\n";
// Write the new content string to the file
file_put_contents($file_path, $file_contents);
print("Address added successfully. Updated book:<br /><br />");
echo($file_contents);
}
else
{
echo("Both form elements must be set. \n");
}
?>
//HTML for submission box?>
<form action="<?php echo $_SERVER['PHP_SELF']; ?>" method="POST">
<input type="text" name="any_name">
<input type="submit" name="submit">
</form>
Even with no comments it should be self explanatory. I leave the proper error dealing to you.
To answer your question, the error was being caused because the $address_add variable wasn't previously declared. You also added quotes to it, making it a string.

PHP replacing 'editable' areas in html files

I'm working on a tool to replace tagged areas in a html document. I've had a look at a few php template systems, but they are not really what I am looking for, so here is what I am after as the "engine" of the system. The template itself has no php and I'm searching the file for the keyword 'editable' to set the areas that are updatable. I don't want to use a database to store anything, instead read everything from the html file itself.
It still has a few areas to fix, but most importantly, I need the part where it iterates over the array of 'editable' regions and updates the template file.
Here is test.html (template file for testing purposes):
<html>
<font class="editable">
This is editable section 1
</font>
<br><br><hr><br>
<font class="editable">
This is editable section 2
</font>
</html>
I'd like to be able the update the 'editable' sections via a set of form textareas. This still needs a bit of work, but here is as far as I've got:
<?php
function g($string,$start,$end){
preg_match_all('/' . preg_quote($start, '/') . '(.*?)'. preg_quote($end, '/').'/i', $string, $m);
$out = array();
foreach($m[1] as $key => $value){
$type = explode('::',$value);
if(sizeof($type)>1){
if(!is_array($out[$type[0]]))
$out[$type[0]] = array();
$out[$type[0]][] = $type[1];
} else {
$out[] = $value;
}
}
return $out;
};
// GET FILES IN DIR
$directory="Templates/";
// create a handler to the directory
$dirhandler = opendir($directory);
// read all the files from directory
$i=0;
while ($file = readdir($dirhandler)) {
// if $file isn't this directory or its parent
//add to the $files array
if ($file != '.' && $file != '..')
{
$files[$i]=$file;
//echo $files[$i]."<br>";
$i++;
}
};
//echo $files[0];
?>
<div style="float:left; width:300px; height:100%; background-color:#252525; color:#cccccc;">
<form method="post" id="Form">
Choose a template:
<select>
<?php
// Dropdown of files in directory
foreach ($files as $file) {
echo "<option>".$file."</option>"; // do somemething to make this $file on selection. Refresh page and populate fields below with the editable areas of the $file html
};
?>
</select>
<br>
<hr>
Update these editable areas:<br>
<?php
$file = 'test.html'; // make this fed from form dropdown (list of files in $folder directory)
$html = file_get_contents($file);
$start = 'class="editable">';
$end = '<';
$oldText = g($html,$start,$end);
$i = 0;
foreach($oldText as $value){
echo '<textarea value="" style="width: 60px; height:20px;">'.$oldText[$i].'</textarea>'; // create a <textarea> that will update the editable area with changes
// something here
$i++;
};
// On submit, update all $oldText values in test.html with new values.
?>
<br><hr>
<input type="submit" name="save" value="Save"/>
</div>
<div style="float:left; width:300px;">
<?php include $file; // preview the file from dropdown. The editable areas should update when <textareas> are updated ?>
</div>
<div style="clear:both;"></div>
I know this answer is a little more involved, but I'd really appreciate any help.
Not sure if i correctly understand what you want to achieve. But it seems I would do that in jquery.
You can get all html elements that has the "editable" class like this :
$(".editable")
You can iterate on them with :
$(".editable").each(function(index){
alert($(this).text()); // or .html()
// etc... do your stuff
});
If you have all your data in a php array. You just need to pass it to the client using json. Use php print inside a javascript tag.
<?php
print "var phparray = " . json_encode($myphparray);
?>
I think it would be better to put the work on the client side (javascript). It will lower the server work load (PHP).
But as I said, I don't think I've grasped everything you wanted to achive.

my script is not reading *.txt file

I have a form which takes two values. One takes a .txt file, the file at which some links are hard coded and a text field which takes a url. When I press submit it takes that url and checks on every link that is on *.txt file. Hope you understand what I am saying if not then please comment I will clarify it. Now I have problems. My code does not work until the file at which links are, is not at my server. I don't how to handle this problem. I have done my search, I also try mysql but that is not ok for me. My script is this:
Enter your file :<input type="file" name="ufile" />
Enter your site name :<input type="text" name="utext" />
<input type="submit" value="Check" />
Now, my php script is this:
$needle = $_POST['utext'];
$file = $_FILES['ufile'];
$new = file($file, FILE_IGNORE_EMPTY_LINES | FILE_SKIP_EMPTY_LINES);
$new = array_map('trim', $new);
echo 'Total entries are: '.count($new).'<br />';
$found = array();
$notfound = array();
foreach ($new as $check) {
echo "<table border='1'><tr>";
echo "<td>Processing</td> <td>", $check,"</td></tr>";
$a = file_get_contents($check);
if (strpos($a, $needle)) {
echo "<td><font color='green'>Found:</font></td>";
$found[] = $check;
} else {
echo "<td><font color='red'>Not Found</font></td>";
$notfound[] = $check;
}
echo "</tr></table>";
}
echo "Matches ".count($found)."<br />";
echo "Not Matched ".count($notfound);
Is there any reason you never read the documentation about how PHP handles uploads in first place? That would make clear that $_FILES['ufile'] is array, so your code cannot work. If you really want to continue writing code without understanding it first, then replace:
$file = $_FILES['ufile'];
with
$file = $_FILES['ufile']['tmp_name'];

PHP not receiving values for radio buttons

I'm using a PHP webpage to give me a list of all files with a .264 extension in a specific folder. The file is then selected and sent to a command to playback the video on a display attached to the computer.
I'm having difficulties trying to get the radio buttons to maintain their values, so that when they are selected and the form button is pressed, they do not know their values and are therefore not able to execute the script.
I know the script works, because I tested it with just a fill-in-the-blank type form and had no problems.
Now I'm listing the files with a radio button to select the file and submit it to the form to play, but it isn't working as I had hoped.
I've looked around and tried to figure it out. I'm not sure if I need to use a linked list or something instead of an array. This is my first time doing php coding, so I'm not sure where I should start to try to resolve this.
<?php
$FileCount = 0;
$currentdir = '/data/'; //Location of Hard Drive
$dir = opendir($currentdir);
$array = array();
echo '<ul>';
while ($File = readdir($dir)){
//if (is_file($file))
$ext = pathinfo($File, PATHINFO_EXTENSION);
if ($ext == '264'){
$array[] = "$File";
echo "<INPUT class='radio' type='radio' name='FileName' value='$File' /> <span>$File</span><p>";
$FileCount++;
}
}
echo '<form action="test.php" method = "post">';
echo "<INPUT TYPE = 'Submit' name = 'FormSubmit' value = 'Submit'>";
echo '</form>';
if ($_POST['FormSubmit'] == "Submit")
{
echo $_POST["FileName"];
}
Nothing returns with this code. Any help would be great. Thanks.
If you want the values of the radio button controls to be sent along with the form post, then the controls themselves must be children of the form element.
<form method = "post" action = "">
<?php while ($File = readdir($dir)) {
if(pathinfo($File, PATHINFO_EXTENSION) == '264')) { ?>
<input type = "radio" ... >
<?php
}
}
?>
<input type = "submit" value = "Submit" name = "FormSubmit">
</form>
As you have it now, the radio buttons exist outside of the form, so they are not part of the form.
echo '<form action="test.php" method = "post">';
add this code below
while ($File = readdir($dir)){

PHP File Delete Issue?

I have the following HTML form:
<form action='delete.php' method='POST'>
<table>
<div class = '.table'>
<?php
$dir = '../uploads/store/';
$newdir = ereg_replace('\.','',$dir);
if (is_dir($dir)) {
if ($dh = opendir($dir)) {
while (($file = readdir($dh)) !== false) {
if (!preg_match('/^(\.(htaccess|\.)?|index\.html)/',$file)) {
echo "<tr><td><font color = 'white'><a href='$newdir$file'>$file</a></font></td>";
echo "<td><input type='submit' value ='Delete'></td></tr>";
echo "<input align='right' type='hidden' value='$file' name='file'>";
}
}
closedir($dh);
}
}
?>
</div>
</table>
</form>
Which links to the following PHP script:
<?php
session_start();
$file = $_POST['file'];
$dir = '../uploads/store/';
$file = $dir . $file;
opendir($dir);
if(unlink($file)) {
echo "File sucessfully deleted";
$_SESSION['username'] = 'guitarman0831';
header('Refresh: 2;url=http://www.ohjustthatguy.com/uploads/uploads.html');
} else {
echo "Error: File could not be deleted";
$_SESSION['username'] = 'guitarman0831';
header('Refresh: 2;url=http://www.ohjustthatguy.com/uploads/uploads.html');
}
?>
However, when the Delete button is pressed in the HTML form, the item above the one intended to delete is deleted.
Hope this makes sense.
NOTE: I'm not going for security with these scripts, I'm going to work on that later. It's only me using this service right now.
Your HTML form needs to have the various submit buttons pass the value for $file instead of using hidden fields.
The problem is that all of the hidden fields are POSTed to delete.php when you submit the form. Then, since you haven't used the PHP-friendly HTML array variable syntax, PHP uses only the last of these to set the value of $_POST['file']. If you do a var_dump of $_POST in delete.php, you will see what the POSTed input is.
The easiest thing to do, with your current markup, is just to have each submit button be named file and pass $file as its value. i.e. you could do:
<button name="file" value="example.txt" type="submit">Delete</button>
Alternately, you could use radio buttons or some other markup.

Categories