Editing PHP using PHP (admin center) - php

Am developing an admin center where I can edit configuration files (written in PHP). I do NOT want to store these values in a mySQL table (for various reasons). So say my config.php has contents like:
<?php
$option1 = 1;
$option2 = 2;
$option4 = 5;
$option7 = array('test','a','b',c');
?>
Now say in one of the admin pages I will only be changing a few values like option2 or option4 etc. Any ideas on what would be the best way to go about this.
I know one option is to read the PHP file completely and write parts of it using REGEX. Any way to make this more efficent? I don't want the config.php file to break because of some error on the user's end. Any ideas on how to ensure that it works?

If you have some liberty about the way you store configuration values, you may use ini files.
All you have to do is load the content of the ini file in an array with parse_ini_file, then modify values in that array and finally overwrite the file with new values, as described in this comment.
For obvious security reasons it's a good idea to place those files out of your document root.
sample content of ini file :
[first_section]
one = 1
five = 5
animal = BIRD
[second_section]
path = "/usr/local/bin"
URL = "http://www.example.com/~username"
sample code (using safefilewrite function) :
<?php
$ini_file = '/path/to/file.ini';
$ini_array = parse_ini_file($ini_file);
$ini_array['animal'] = 'CAT';
safefilerewrite($file, implode("\r\n", $ini_array));
?>

var_export() is probably the function you're looking for.

You can write/read the settings to a file using the following code:
$content = array();
//fill your array with settings;
$fh = fopen ( $bashfile, 'w' ) or die ( "can't open file" );
fwrite ( $fh, $content );
fclose ( $fh );
to read it you use:
file_get_contents() //this will return a string value
OR
Line by line:
$lines = file('file.txt');
//loop through our array, show HTML source as HTML source; and line numbers too.
foreach ($lines as $line_num => $line) {
print "Line #<b>{$line_num}</b> : " . htmlspecialchars($line) . "<br />\n";
}

Related

PHP write to flat text file. New to PHP, learning. I have the read working. Need to write back updates

I have a flat file, TestFile.txt, that contains about 200 lines. Each item is a separate row. I show a partial of the contents of the TestFile.txt file below. I have PHP code working that reads TestFile.txt exactly as I need. The PHP read code searches the TestFile.txt, locates the line I wish to read, and places the result into an html input box. It parses the text after the = in the line, and only displays the data found after the =. Just as I need. Now I need to change the data in the html input box, and write the change back to TestFile.txt, and only update the text after the =. I show the PHP read code below. I have not a clue how to do what I need. I am a little over a week studying PHP. Any help with writing is much appreciated.
Thanks,
Mitch
Partial TestFile.txt:
RXFrequency=432675000
TXFrequency=432675000
RXOffset=260
TXOffset=120
Network=mnet.hopto.org
Password=9Yg81prqL0363zt
Latitude=34.657783
Longitude=-3.784595
Port=62021
Part of the PHP:
<!DOCTYPE html>
<html>
<body>
<?php
// Place text to look for in string $Search_String.
// The $Search_String will remain hard coded in my production
// code. The users will not be able to select $Search_String.
$Search_String_1 = "RXOff";
// Identify Text File, open File and Read the File.
$MyFile = fopen("TestFile.txt", "r") or die("Unable to open file!");
$found= "False";
// Create the while loop. Test each line with the if statement,
// looking for $Search_String, and place the result into string $line.
// Next, echo string $line which containes the found line in the
// flat text file. It will return the entire line even from a
// partial $Search_String, which is what I want.
/*...*/
// Next, let us build the array.
$lines = [];
while ( $line = fgets( $MyFile ) ) {
if ( str_contains( $line, $Search_String_1 ) ) {
//here you are keeping track of each line matching the criteria.
$lines[] = $line;
// This explode function will split the string contained
// in the $line variable at the =. Text left of the = is
// placed into the $key variable. Text right of the = is
// placed into the $value variable.
[$key, $value] = explode("=", "$line");
// echo $key; // RXOffset;
// echo $value; // 260;
//echo $line;
//echo $Search_String_1;
}
}
?>
<?php foreach($lines as $line): ?>
<?php endforeach;
// Properly close the text file.
fclose($MyFile);
// Get string $value from the explode code above.
?>
<label>RXOffset: <input type="text" id="message" value="<?php echo $value;?>"/></label>
<?php
</body>
<html>
Hope this gives enough information. Feel free to comment questions.
Thanks,
Mitch
This is what appears on the browser when I execute this PHP:
RXOffset: 269
Label Data

Copy Multiple Images From Remote Server

I am trying to copy multiple images from a remote host (using a URL) to my local box (using XAMPP on my local box to execute the script).
I am using copy(). When I go to execute the copy(), only the LAST image in the array is created. So, if I have 5 image links, only the 5th image gets created and nothing prior even gets a file created.
I have tried CURL and FOpen and then both create all of the files, but all of the files are blank except, again, the last file which is perfectly fine.
$txt_file = file_get_contents('urls_for_images.txt');
if(!empty($txt_file)){
$image_links = explode("\n", $txt_file);
$i = 1;
foreach($image_links as $image_link){
$file_info = pathinfo($image_link);
copy($image_link, 'images/00' . $i . '_original.' . $file_info['extension']);
$i++;
}
}
I am not sure where the problem is occurring, but it seems odd to me that it will copy the last image in the text file, but not any of the others.
Thanks for the help in advance!
The i variable never changes, therefore the code tries to copy a file with the same name over and over again and only the last file is saved.
Try modifying your code this way:
$txt_file = file_get_contents('urls_for_images.txt');
if(!empty($txt_file)){
$image_links = explode("\n", $txt_file);
$i = 1;
foreach($image_links as $image_link){
$file_info = pathinfo($image_link);
copy($image_link, 'images/00' . $i . '_original.' . $file_info['extension']);
$i++;
}
}
You'd be better off with just file(), which reads the file into an array automatically:
$files = file('urls_for_images.txt', FILE_IGNORE_NEW_LINES);
foreach($files as $remote_file) {
$local_file = ....;
copy($remote_file, $local_file);
}
It appears the problem is the text file which line endings are \r\n and you are exploding with only \n. The quickest way to fix this is either explode by \r\n; or trim with default parameters to remove \r from the end of each line.
foreach($image_links as $image_link){
$image_link = trim($image_link);
$file_info = pathinfo($image_link);
...
}
However, the cleanest way to do this is to use file function, which handles line endings automatically. I recommend you to use this approach.

Read each line of text of each file in a directory and place into array?

I have a directory with text files in it and new text files getting added each day. Each text file is a school lesson with 4 lines of text. Line 1 is Lesson Number, line 2 is Lesson Title, line 3 is Description, and line 4 is Due Date.
I need, in PHP, to be able to read all current and future text files and place them into an HTML table. 4 columns in a table labeled Lesson Number, Lesson Title, Description, and Due Date. Each text file being 1 table row.
I've made a site to help out some homeschooled students but wanted to add this functionality to the site to help them view all past, present, and future lessons. I know a little PHP but can't wrap my head around it and it seems the more I try the more I'm getting confused. This is a learning experience for me.
I've tried using fopen but can only get it to open a text file and not a whole directory. I was thinking I need to get a directory listing, place that into an array, and use fopen to open each file in the array but I may be way off. Any help to point me in the right direction is greatly appreciated!
Your approach is one way of doing it. You could scan the directory for the files you need, and use the file() function to retrieve file contents in an array. I will only post partial code, as getting file names from a directory is obvious (see glob() in other answers).
//got file list from a given directory in an array (array would contain file names).
//it is recommanded, that file names to be with full path, or a relative path to the script
$task_array = Array();
foreach ($filelist as $filename)
{
try
{
$file_content = file($filename); // we get an array with this function
// you could do this the other way, by using fopen() and fread(), but this is easier
}
catch(Exception $e)
{
$(file_content = false;
}
if (($file_content !== false) && (!empty($file_content)))
{
$task_array[] = $file_content;
}
}
Your task array will become a two-dimensional array, like this:
Array(
[0] -> Array(
[0] -> 1
[1] -> 'Lesson Title'
[2] -> 'Lesson Description here'
[3] -> '2013-09-25'
)
[1] -> Array(
[0] -> 2
[1] -> 'Lesson Title 2'
[2] -> 'Lesson 2 Description here'
[3] -> '2013-09-25'
)
)
Then, when you have this array, you could use foreach again, to display it in HTML.
However, if you would want to do this the right way, you should use a database, for example MySQL.
You could go two ways with this either go with glob which will scan the directory or the better Directory Iterator http://php.net/manual/en/class.directoryiterator.php which i would recommend with the glob method is a bit easier so ill go with that.
It depends with you are already storing the previous records or not but either way ill try to get some examples on here.
I have now improved and tested the below code because the other one i wrote was rubbish
<?php
/**
* #author - Sephedo
* #for - Randall # Stackoverflow
* #question - http://stackoverflow.com/questions/18704981/read-each-line-of-text-of-each-file-in-a-directory-and-place-into-array/18705231#18705231
*/
$directory = 'lessons/'; // The directory to the lesson text files
$linesToReturn = 4; // Set to four for the number of lines in each text file ( for expansion? )
// Find all files in the directory which are .txt files
foreach( glob( $directory . "*.txt" ) as $filename )
{
// Open the file
if( $handle = #fopen( $filename, "r") )
{
$x = 0; // Start the line counter
// Cycle each line until end or reach the lines to return limit
while(! feof( $handle ) or $x < $linesToReturn )
{
$line = fgets($handle); // Read the line
$lessons[$filename][] = $line;
$x++; // Increase the counter
}
// This lines makes sure that are exactly 4 lines in each lesson
if( count( $lessons[$filename] ) != $linesToReturn ) unset( $lessons[$filename] );
}
}
// creates a blank list if no files or valid files were found.
if(! isset( $lessons ) ) $lessons = array();
// The rest of the page just builds a simple table to display each lesson.-
echo '<h1>Lesson Plans</h1>';
echo '<table>';
echo '<th>Lesson Number</th><th>Lesson Title</th><th>Description</th><th>Due Date</th>';
foreach( $lessons as $file => $details )
{
echo '<tr><td>' . $details[0] . '</td><td>' . $details[1] . '</td><td>' . $details[2] . '</td><td>' . $details[3] . '</td></tr>';
}
echo '</table>';
?>
This is how I would traverse a directory and read files:
$dir = "/YOUR_DIRECTORY_PATH/*";
foreach(glob($dir) as $file) { //load each file in the directory
$fileHandle = fopen($file, "r");
while (!feof($fileHandle)) { // load each line
$line = fgets($fileHandle);
echo $line . '<br />';
}
fclose($fileHandle);
}

Append at the beginning of the file in PHP [duplicate]

This question already has answers here:
Need to write at beginning of file with PHP
(10 answers)
Closed 9 years ago.
Hi I want to append a row at the beginning of the file using php.
Lets say for example the file is containing the following contnet:
Hello Stack Overflow, you are really helping me a lot.
And now i Want to add a row on top of the repvious one like this:
www.stackoverflow.com
Hello Stack Overflow, you are really helping me a lot.
This is the code that I am having at the moment in a script.
$fp = fopen($file, 'a+') or die("can't open file");
$theOldData = fread($fp, filesize($file));
fclose($fp);
$fp = fopen($file, 'w+') or die("can't open file");
$toBeWriteToFile = $insertNewRow.$theOldData;
fwrite($fp, $toBeWriteToFile);
fclose($fp);
I want some optimal solution for it, as I am using it in a php script. Here are some solutions i found on here:
Need to write at beginning of file with PHP
which says the following to append at the beginning:
<?php
$file_data = "Stuff you want to add\n";
$file_data .= file_get_contents('database.txt');
file_put_contents('database.txt', $file_data);
?>
And other one here:
Using php, how to insert text without overwriting to the beginning of a text file
says the following:
$old_content = file_get_contents($file);
fwrite($file, $new_content."\n".$old_content);
So my final question is, which is the best method to use (I mean optimal) among all the above methods. Is there any better possibly than above?
Looking for your thoughts on this!!!.
function file_prepend ($string, $filename) {
$fileContent = file_get_contents ($filename);
file_put_contents ($filename, $string . "\n" . $fileContent);
}
usage :
file_prepend("couldn't connect to the database", 'database.logs');
My personal preference when writing to a file is to use file_put_contents
From the manual:
This function is identical to calling fopen(), fwrite() and fclose()
successively to write data to a file.
Because the function automatically handles those three functions for me I do not have to remember to close the resource after I'm done with it.
There is no really efficient way to write before the first line in a file. Both solutions mentioned in your questions create a new file from copying everything from the old one then write new data (and there is no much difference between the two methods).
If you are really after efficiency, ie avoiding the whole copy of the existing file, and you need to have the last inserted line being the first in the file, it all depends how you plan on using the file after it is created.
three files
Per you comment, you could create three files header, content and footer and output each of them in sequence ; that would avoid the copy even if header is created after content.
work reverse in one file
This method puts the file in memory (array).
Since you know you create the content before the header, always write lines in reverse order, footer, content, then header:
function write_reverse($lines, $file) { // $lines is an array
for($i=count($lines)-1 ; $i>=0 ; $i--) fwrite($file, $lines[$i]);
}
then you call write_reverse() first with footer, then content and finally header. Each time you want to add something at the beginning of the file, just write at the end...
Then to read the file for output
$lines = array();
while (($line = fgets($file)) !== false) $lines[] = $line;
// then print from last one
for ($i=count($lines)-1 ; $i>=0 ; $i--) echo $lines[$i];
Then there is another consideration: could you avoid using files at all - eg via PHP APC
You mean prepending. I suggest you read the line and replace it with next line without losing data.
<?php
$dataToBeAdded = "www.stackoverflow.com";
$file = "database.txt";
$handle = fopen($file, "r+");
$final_length = filesize($file) + strlen($dataToBeAdded );
$existingData = fread($handle, strlen($dataToBeAdded ));
rewind($handle);
$i = 1;
while (ftell($handle) < $final_length)
{
fwrite($handle, $dataToBeAdded );
$dataToBeAdded = $existingData ;
$existingData = fread($handle, strlen($dataToBeAdded ));
fseek($handle, $i * strlen($dataToBeAdded ));
$i++;
}
?>

parsing an array into a lightbox comment

ok guys need your help again,
previously you all introduced me lightbox which after some tweaking has been great. except while using my php code there doesn't seem to be a way to add a caption to the image. now a friend of my introduced me to array using a .txt file. now this is all fine and dandy but i can't seem to get the code that we came up with to read the file correctly. currently it is randomly pulling the letter "a" and the letter "p" and assigning that, which i have no clue where it is getting this.
now here is the code that i've come up with to get the contents of the file.
<?php
// process caption file into named array
//open the file
$myFile = "captions.txt";
$fh = fopen($myFile, 'r') or die("Can't open file");
$theData = explode(fread($fh, filesize($myFile)),"\n");
//close the file
fclose($fh);
//parse line by line until there is no data left.
foreach ($theData as $item => $line) {
$exploded = explode("=", $line);
if (count($exploded) == 2) {
$myFile[$exploded[0]] = $exploded[1];
}
}
?>
and then i'm using the code that auto-populates my image album in turn activating the lighbtox.
<?php
$images = glob('*.{jpg,jpeg,png,gif}', GLOB_BRACE);
foreach ($images as $image) {
if (file_exists("./thumbs/{$image}")){
echo "<img src=\"thumbs/{$image}\" alt=\"{$image}\" />";
}
}
?>
using this code generates no errors but doesn't properly read the captions file.
what i'm wanting to do is have the text file setup with the file name seperated by a = and then the caption.
here is a link to my test page if anyone wants to take a look.
http://outtamymindphoto.myftp.org/images/testalbum/testpage.php
You should start by fixing this line:
$theData = explode(fread($fh, filesize($myFile)),"\n");
According to the PHP Manual , the delimeter is the first parameter.
(array explode ( string $delimiter , string $string [, int $limit ] ))
(Read more about explode - http://php.net/manual/en/function.explode.php)
The right way:
$theData = explode("\n" , fread($fh, filesize($myFile)));
You'll also should try to output the variables in order to locate the problem.
For instance , use var_dump($var) to check $vars value.
Hope I helped you,
comment if you need further help.

Categories