I have a standard config file: $variable = 'value';, but at the last moment came up to use the web interface to configure it. So what is the best way to read the file, find the value of variables and then resave the file again?
At the moment I have 2 ideas:
1) RegExp
2) Keep somewhere array example
Store all config values in an associative array like so:
$config = array(
'variable' => 'value'
);
For the web interface, you can easily loop over the entire array:
foreach($config as $key=>$value) { ... }
After making changes, loop over the array and write it back to the file. (You really should be using a DB for this, though).
When you include the file, you can either use it like this:
include('config.php');
echo $config['variable']
// or
extract($config);
echo $variable;
Note: If you extract, it will overwrite any variables by the same name you might have defined before extracting.
PS - To make it easier to read and write to and from a file, I would just use json encoding to serialize the array.
Use a db
If your config is user defined - it would be better to store the config in a database. Otherwise you have this "novel" problem to solve but also potentially introduce security problems. I.e. for any one user to be able to edit your config files - they must be writeable to the webserver user. That opens the door to injecting malicious code into this file from a web exploit - or simply someone with direct access to your server (shared host?) finding this writeable file and updating it to their liking (e.g. putting "<?php header('Location: my site'); die;" in it).
One config variable
If you must manage it with a config file, include the file to read it, and var_export the variables to write it. That's easiest to do if there is only one config variable, that is an array. e.g.:
function writeConfig($config = array()) {
$arrayAsString = var_export($config, true);
$string = "<?php\n";
$string .= "\$config = $arrayAsString;\n";
file_put_contents('config.php', $string);
}
Allow partial updates
If you are changing only some variables - just include the config file before rewriting it:
function writeConfig($edits = array()) {
require 'config.php';
$edits += $config;
$arrayAsString = var_export($edits, true);
$string = "<?php\n";
$string .= "\$config = $arrayAsString;\n";
file_put_contents('config.php', $string);
}
Multiple config variables
If you have more than one variable in your config file, make use of get defined vars and loop on them to write the file back:
function writeConfig($_name = '', $_value) {
require 'config.php';
$$_name = $_value; // This is a variable variable
unset($_name, $_value);
$string = "<?php\n";
foreach(get_defined_vars() as $name => $value) {
$valueAsString = var_export($value, true);
$string .= "\$$name = $valueAsString;\n";
file_put_contents('config.php', $string);
}
}
The above code makes use of variable variables, to overwrite once of the variables in the config file. Each of these last two examples can easily be adapted to update multiple variables at the same time.
Related
I am trying to make a PHP application which searches through the files of your current directory and looks for a file in every subdirectory called email.txt, then it gets the contents of the file and compares the contents from email.txt with the given query and echoes all the matching directories with the given query. But it does not work and it looks like the problem is in the if-else part of the script at the end because it doesn't give any output.
<?php
// pulling query from link
$query = $_GET["q"];
echo($query);
echo("<br>");
// listing all files in doc directory
$files = scandir(".");
// searching trough array for unwanted files
$downloader = array_search("downloader.php", $files);
$viewer = array_search("viewer.php", $files);
$search = array_search("search.php", $files);
$editor = array_search("editor.php", $files);
$index = array_search("index.php", $files);
$error_log = array_search("error_log", $files);
$images = array_search("images", $files);
$parsedown = array_search("Parsedown.php", $files);
// deleting unwanted files from array
unset($files[$downloader]);
unset($files[$viewer]);
unset($files[$search]);
unset($files[$editor]);
unset($files[$index]);
unset($files[$error_log]);
unset($files[$images]);
unset($files[$parsedown]);
// counting folders
$folderamount = count($files);
// defining loop variables
$loopnum = 0;
// loop
while ($loopnum <= $folderamount + 10) {
$loopnum = $loopnum + 1;
// gets the emails from every folder
$dirname = $files[$loopnum];
$email = file_get_contents("$dirname/email.txt");
//checks if the email matches
if ($stremail == $query) {
echo($dirname);
}
}
//print_r($files);
//echo("<br><br>");
?>
Can someone explain / fix this for me? I literally have no clue what it is and I debugged soo much already. It would be heavily gracious and appreciated.
Kind regards,
Bluppie05
There's a few problems with this code that would be preventing you from getting the correct output.
The main reason you don't get any output from the if test is the condition is (presumably) using the wrong variable name.
// variable with the file data is called $email
$email = file_get_contents("$dirname/email.txt");
// test is checking $stremail which is never given a value
if ($stremail == $query) {
echo($dirname);
}
There is also an issue with your scandir() and unset() combination. As you've discovered scandir() basically gives you everything that a dir or ls would on the command line. Using unset() to remove specific files is problematic because you have to maintain a hardcoded list of files. However, unset() also leaves holes in your array, the count changes but the original indices do not. This may be why you are using $folderamount + 10 in your loop. Take a look at this Stack Overflow question for more discussion of the problem.
Rebase array keys after unsetting elements
I recommend you read the PHP manual page on the glob() function as it will greatly simplify getting the contents of a directory. In particular take a look at the GLOB_ONLYDIR flag.
https://www.php.net/manual/en/function.glob.php
Lastly, don't increment your loop counter at the beginning of the loop when using the counter to read elements from an array. Take a look at the PHP manual page for foreach loops for a neater way to iterate over an array.
https://www.php.net/manual/en/control-structures.foreach.php
I used php real path to get actual path of files and directory to delete and after deleted i will print all deleted
items. But my problem is that it also show the real path where the file source is and i don't want to show it to users
is there any way i can hide the pay and only show the file example.
I don't like it to look like this
[File]: /mnt/wef66/d2/81/557642661/htdocs/useruploads/myfiles/imagefolder/mosaic_1.jpg
[File]: /mnt/wef66/d2/81/557642661/htdocs/useruploads/myfiles/imagefolder/room_home_1.jpg
[Directory]: /mnt/wef66/d2/81/557642661/htdocs/useruploads/myfiles/imagefolder
Is there anyway i can make it look this way using rejex or any method please i need help i have to remove /mnt/wef66/d2/81/557642661/htdocs/
[File]: www.example.com/useruploads/myfiles/imagefolder/mosaic_1.jpg
[File]: www.example.com/useruploads/myfiles/imagefolder/room_home_1.jpg
[Directory]: www.example.com/useruploads/myfiles/imagefolder
Maybe using something like this
echo preg_replace("/mnt/wef66/d2/81/557642661/htdocs", "www.example.com", "[File]: /mnt/wef66/d2/81/557642661/htdocs/useruploads/myfiles/imagefolder/mosaic_1.jpg");
$path = realpath($parentBas);
I would use configuration variables $privatePath and $publicPath.
So you can concat whichever you want to the relative paths to your directories or files.
For your example:
$privatePath = '/mnt/wef66/d2/81/557642661/htdocs/';
$publicPath = 'www.example.com/';
$pic1RelativePath = 'useruploads/myfiles/imagefolder/mosaic_1.jpg';
$pic1privatePath = $privatePath . $pic1RelativePath;
// /mnt/wef66/d2/81/557642661/htdocs/useruploads/myfiles/imagefolder/mosaic_1.jpg
$pic1publicPath = $publicPath . $pic1RelativePath;
// www.example.com/useruploads/myfiles/imagefolder/mosaic_1.jpg
I think this is easier and more efficient than replacing the paths with regex.
EDIT:
If you have all the real paths in an array, you can loop through it and replace easily all the private paths with the public paths this way:
$paths = [
'/mnt/wef66/d2/81/557642661/htdocs/useruploads/myfiles/imagefolder/mosaic_1.jpg',
'/mnt/wef66/d2/81/557642661/htdocs/useruploads/myfiles/imagefolder/room_home_1.jpg',
'/mnt/wef66/d2/81/557642661/htdocs/useruploads/myfiles/imagefolder'
];
foreach ($paths as &$path) {
$path = str_replace($privatePath, $publicPath, $path);
}
print_r($paths);
Is there anyway to access variables of one php file into another?
- I am trying to validate a form. I need to access variables from the validationConditions.php file in form.php file.
I have tried creating sessions but they are error prone.
I am using the latest version of dreamweaver.
Is it possible to use $_POST to achieve the results?
Any example will be welcome...
Thanks a lot in advance.
The easiest would be to use session variables. In the first page you could set the values like this
session_start();
$_SESSION['myvar'] = 'My Data';
Then in the second page you can retrieve the data like this...
session_start();
$myvar = $_SESSION['myvar'];
Which in turn sets $myvar to "My Data"
You can read a php file with another php file. Assume that we have 2 php files.
new.php
<?php
$a="something";
?>
serach.php ---> search in new.php
<?php
// What to look for
$search = '$a'; //WE are searching $a
$lines = file('new.php'); // in new.php
foreach($lines as $line)
{
// Check if the line contains the string we're looking for, and print if it does
if(strpos($line, $search) !== false)
echo $line;
}
?>
Something like that. You have to edit this file.
A somehow devious solution:
ob_start();
$request = array(
"_id"=>"0815",
"user"=>"john",
"email"=>"john#dunbar.com",
"phone"=>NULL
); // Don't know. Just how u need your request to look like.
include('validationConditions.php');
$response = getValidationConditions($request); // Function in 'validationConditions.php' that responds an array or a JSON
$out = ob_get_clean();
echo json_encode($out);
In a project, I need to load some basic config without database query, how to creat a function to edit this file.
config.php may like this:
<?php
define(DEBUG, TRUE);
define (LANG, 'en');
define(THEME, 'joy');
define(DB_NAME, 'cms');
define(DB_USER, 'root');
define(DB_PASSWORD, '000');
define(DB_HOST, 'localhost');
define(CACHE, '3600');
define(CLOSE, TRUE);
.....
ajax.php
$key = $_POST['key'];
$value = $_POST['value'];
function change_config($key,$value){
// how ?
}
if I want to change cache time, I can run change_config('CACHE','1800')
if I want to change debug value, I can run change_config('DEBUG',false)
You could always take the easy route and use runkit_constant_redefine
runkit_constant_redefine($key, $value);
But of course, constants were built to be static. Editing that file directly means properly sanitizing input, and rewriting the file from the top to bottom every time. If the file size doesn't change and nor does the constant value's length, then you can use fwrite to write at the exact block where it exists, but that's generally not a solution. That said, use a database. they're not hard to learn.
Edit
When I was referring to using a database, I was implying the settings other than the DB connection, which should be static, or should change using something like Environment Variables, not being edited manually.
You could do something like this:
<?php
$key = $_POST['key'];
$value = $_POST['value'];
require_once 'config.php';
function change_config($key,$value){
$newContent = "<?php \n
define(DEBUG, " . ($key == "DEBUG"?$value:DEBUG) . "); \n
define(LANG, '" . ($key == "LANG"?$value:LANG) . "'); \n
define(THEME, '" . ($key == "THEME"?$value:THEME) . "'); \n";
file_put_contents('config.php', $newContent);
}
Your overwriting the file with the new content. We create an string wich will hold the content of the NEW config.php file. The \n are for new lines.
Then we go past all the define lines and put them in the string. For the value we use an Ternary Operator. Simply said, that's an if statement which will check if the key is corresponding the define where building. If so we will put the new value in it. If not, we will enter the OLD CONFIG.php value.
I want to include my header into a script that uses smarty templates. From searching this site, I am partially there, but not quite:
{include file='/home/username/public_html/header.php'}
This successfully includes the image in the header, but neither of two includes the header contains. One of the includes is a php file, and the other is html (my bootstrap nav bar). I seems from my searches that I need to make a plugin, which according to one post is "easy", but I can't find an example of how to accomplish this?
based on codefreaks inststructions, here's what I did. I'm sure the instructions are correct, I'm just not interpreting them correctly, as this isn't displaying anything.
Here are the three files, with their paths in relation to the public_html directory, and what I added to them. Everything is exactly as I put it: no words here are placeholders.
file 1
sitewide/myheader.php
<?
ob_start();
--- I didn't change the original content here --
$output = ob_get_contents();
ob_end_clean(); ?>
File 2
newscript/includes/page_header.php
$smarty = new Smarty();
require "/home/username/public_html/sitewide/myheader.php";
$smarty->assign('myheader', $output);
$smarty->display('../themes/default/template/header.tpl');
File 3
newscript/themes/default/template/header.tpl
{$myheader}
I dont think you can include your php file in smarty.
As samrty is a template engine,
PHP pages executes first, then it sends the data to your smarty page.
Solution : Pass all data needed from php page to smarty, and include html page, with smarty variables.
After getting feedback from you and testing myself, I figured out you might not have set up smarty properly. Follow instructions at http://www.smarty.net/quick_install to install it properly. My final directory structure after setting up properly looks like:
Once you have it set it up properly this is code I used in files:
index.php
<?php
echo "hello";
require_once "libs/Smarty.class.php";
$smarty = new Smarty();
$smarty->setTemplateDir('smarty/templates');
$smarty->setCompileDir('smarty/templates_c');
$smarty->setCacheDir('smarty/cache');
$smarty->setConfigDir('smarty/configs');
require "header.php";
$smarty->assign('header', $output);
$smarty->testInstall();
$smarty->display('smarty.tpl');
echo "hello";
?>
header.php:
<?php
ob_start();
?>
hello honey bunny
<?php
$output = ob_get_contents();
ob_end_clean();
?>
Put smarty.tpl in templates folder!
{$header}hellos
I am trying to do a very similar thing except all I want is some global PHP constants that I have defined in a stand alone constants.php file using define.
I want those same said constants in my smarty templates so I've been trying to include constants.php in the smarty template but this is better a better way to do this:
In constants.php
$_CONSTANT['TBL'] = TRUE;
$_CONSTANT['FLD'] = FALSE;
$_CONSTANT['DB_READ_SUCCESS'] = 1;
$_CONSTANT['DB_WRITE_SUCCESS'] = 1;
$_CONSTANT['DB_WRITE_ERROR_UNKNOWN'] = -100;
//*** Copy the $_CONSTANT array to PHP define() to make global PHP constants
foreach($_CONSTANT as $key => $value) {
define($key, $value);
}
Then in my smarty set up function I do this:
foreach ($_CONSTANT as $key => $value) {
Smarty->assign($key, $value);
}
And really I think variable (or constant) values is all you really want in your Smarty templates to keep your view layer separate from your model and controller layers.
Post Script:
In fact you can use this technique to pass your PHP constants, using Smarty, to JavaScript allowing you to declare you constants in one place for three different environments: PHP, Smarty, and JavaScript.
Here's how:
Call the following from your smarty set up function:
public function AssignJSConstants($values) {
$js = '';
foreach ($values as $key => $value) {
if ($key != 'CR') {
if (is_string($value)) {
$js = $js.$key.' = "'.$value.'";';
} else {
$js = $js.$key.' = '.$value.';';
}
$js = $js.CR.' ';
}
}
$this->Smarty->assign('JavaScriptConstants', $js);
}
And then declare the following in your smarty template:
<script>
//php constants that exported to JavaScript
{$JavaScriptConstants}
</script>
Which will give you this in your HTML:
<script>
//php constants that exported to JavaScript
TBL = 1;
FLD = 0;
DB_READ_SUCCESS = 1;
DB_READ_ERROR_UNKNOWN = -10;
DB_WRITE_SUCCESS = 1;
DB_WRITE_ERROR_UNKNOWN = -100;
</script>