Need suggestion to edit a php through php - php

I have a config file which is written in PHP as below,
<?php
class WebConfig {
public static $WEBPATH = '/customers';
public static $ACCOUNTPATH = '/empaccountpath';
public static $INFO = '/accountInfo';
const ACCOUNT_STATUS = '/account_status';
const ENABLE_SEARCH = '/enable_search';
}
?>
So I would like to develop an interface in PHP, which has ability to edit the file values such as $WEBPATH, $ACCOUNTPATH and const values.
Simple PHP editor script will do the above work. But it doesn't check the syntax.
Please suggest how to do it in PHP efficiently.

Better solutions
Many other configuration storage formats are better suited for this kind of thing. Look into php file returns array, ini, json, xml or yaml.
"PHP file returns array" is a simple PHP file which looks like this
return(
array(
'config_key' => 'config_value'
)
);
?>
The return value of this file can be retrieved by your code when you're including it: $x = include('file.php'); and $x will have the values in the array.
INI is simple & intuitive to read or write for humans. It has a limited structure. PHP can read it with one function but it has write capabilities only in a separate (non-default) package. Which means you have to generate the ini files yourself.
JSON is "fairly" simple & intuitive to read or write for humans. It has a flexible structure extensible structure. PHP can read and write to a JSON file using only a couple of functions. Unfortunately PHP does not retain JSON pretty-print formatting so after you overwrite a file, it'll be all in one line, harder to read after that.
XML is simple & intuitive to read for humans, it can be very informative because it's quite verbose about what everything is. I has a structure almost as flexible as JSON and it is extensible. PHP can read and write to an XML but doing so means using a handful of lines of code (5-10 for simple stuff).
YAML is another option which is easy to read and write for humans, PHP doesn't have direct YAML support but there are other options (see below). It's structure is flexible and extensible. For me personally understanding YAML has been less intuitive.
Zend_Config can be used as an interface to reading/writing any of the above formats and can be used to abstract the file format itself and offer your application a format-agnostic way of handling configurations.
You could also use the database to store your configuration or a separate SQLite database dedicated to storing configurations in general -- this is usually used when many configurations need to be retained in a fine grained searchable format that allows various types of layered overriding (ex.: general defaults, controller defaults, action defaults, particular case defaults).
How to do it in PHP
You don't need to create a language parser as #geomagas said. Using include or require is enought, the PHP interpreter will load the "new" class into memory and ensure it is available.
All you need to do is create a template file in which to replace some values such as:
<?php
class WebConfig {
public static $WEBPATH = '$_replace_webpath';
public static $ACCOUNTPATH = '$_replace_accountpath';
public static $INFO = '$_replace_info';
const ACCOUNT_STATUS = '$_replace_account_status';
const ENABLE_SEARCH = '$_replace_enable_search';
}
And then load read the file, and replace it with the current values such as:
$config_template = file_get_contents('/path/to/config/template.php.template');
str_replace(
array('$_replace_webpath' ... ),
array('/customers' ... ),
$config_template
);
PrestaShop uses PHP files for configuration. It rewrites them when needed.

Directly to access the PHP Class file too danger....Many security issues....
Could we use simple html form to let user to edit.
Using JSON format to store into file.
PHP encode & decode by json_encode() & json_decode(), when save & read the value.

Related

PHP - Laravel 8 dynamic namespace use

Good afternoon, I'm looking for an elegant method with passing a namespace, an example:
use App\Services\SuppliersApiParsers\parserName;// I plan to create a bunch of parsers in this folder, each with its own file, i.e. parserName1, parserName2
class SuppliersPrice implements SuppliersPriceInterfaces
{
//..
private function getSuppliers($store_supplier)
{
$parser= SuppliersApiStoreSet::where('store_supplier', $store_supplier)
->first();
$parserFile = $parser->file;
echo parserName::showBasicFunction();
//Но хочу: $parserFile::showSupplierBrandList();
}
}
//I can write example:
$nameFun = 'getSuppliers';
echo self::$nameFun($store_supplier);
//But not :
$nameClass = 'parserName';
use App\Services\SuppliersApiParsers\$nameClass;
All parsers will have typed data as output, but the magic of obtaining them will be hidden in each file. I will pull the names of these files from the database, depending on the needs of the request.
Now I'm thinking about file inclusions, but I don't find that a good option.
I expect a universal mechanism for connecting parsers.

best practice for internationalizing white-labeled PHP code

I have a code base that can be customized for different customers. This is handled, in most instances, by loading a class with constants specific to each customer, but with the same class name. Class name collision is managed, and, obviously, only one is loaded at a time.
class Customer () {
const CUST_NAME = 'Alpha Corp.';
}
class Customer () {
const CUST_NAME = 'Beta, Inc.';
}
For each customer, I also want the code to be internationalized. So, a program can draw its displayed text from a language-specific source, but also still be dynamic with regard to customer-specific information. Assume the customer-specific information is indifferent toward i18n. This reduces the number of files from one per customer per language, to just one per language. The desired result is to implement something similar to
// in separate language files:
$greeting = 'Hello. Welcome to ';
$greeting = 'Hola. Bienvenido a ';
// in front-end
$greeting = get $greeting in desired language;
echo $greeting, Customer::CUST_NAME, "\n";
The best solution I can devise to meet these requirements is an i18n class (or family of classes), which would handle multiple customers and/or multiple languages. However, it is execution-expensive to call methods, as opposed to string literals or constants. The methods would combine translations from constants or external sources, and combine them with values from the Customer class. (I am stuck with PHP 5.2 for now, so the niceties of heredoc for class properties/constants is unavailable.)
class i18n_en () {
const GREETING = 'Hello. Welcome to ';
static public function getGreeting () {
return self::GREETING . Customer::CUST_NAME;
}
}
Alternatively, I can write a script for a "template approach", in which I maintain a template file of the class, with text placeholders. The customer-specific files are generated at the time of customer creation from these templates. It would be easy to generate or re-generate files as needed, but I'm back to needing a separate file for each customer for each language. Thus, it doesn't meet my need as nicely.
Surely, I'm not the first to face this problem. Can anyone offer alternatives or best practices? Since the code will execute many times more than I'll create a new customer, I prefer run-time efficiency to ease of maintenance. Of course, a great solution will offer both.
There are two tried and true methods for PHP internationalization.
The most prevalent is to create huge language arrays like so:
define('MSG__GREETING', 1);
$lang['en_US'] = array(MSG__GREETING => 'Hello, and welcome to ');
$lang['fr_FR'] = array(MSG__GREETING => 'Bonjour, et bienvenue à ');
$selectedLang = 'fr_FR';
echo $lang[$selectedLang][MSG__GREETING] . 'Fhloston Paradise';
Unfortunately, this gets very tedious very quickly.
The ideal method, which I've used numerous times, is the accepted method of internationalization for Linux apps: il8n, via PHP's gettext extension.
With this method, you basically end up doing stuff like this:
setenv('LANG=fr_FR');
echo _('Hello, and welcome to ') . 'Fhloston Paradise';
and then in il8n files (called .po) you have each translation. It's actually much easier to maintain and extend over the long run, especially since you can just email your .po files to various translators and they just fill in the blanks, as it were... no coding skills necessary.
Here's a tutorial to get you started: http://kunststube.net/frontback/
Personally, when handling internationalization I have always used templates, specifically Smarty - http://www.smarty.net/ and create language based template. You can also use translation keys in a database, ex table with key, language, translation columns which can be cached this way you aren't calling tons of methods. Also, you can cache the output of all the translation methods in memory using memcached. Tons of ways. Hope some of these help a little.

Constants in Kohana

I've used codeigniter in the past but on my current project I'm making the switch to Kohana. What is the best practice on constants?
In codeigniter there is the actual constants.php, but going through Kohana's source I'm not seeing something similar.
Never used kohana, but after a quick googling I find that you can use the config API to create your own config that will house the constants you need.
This thread suggests that if you are storing database sensitive items, to place them in the database.php config, etc.. making them relative to the type of data they are storing.
I'm familiar with Kohana, but not CI so much, so I'm guessing a bit to what you mean by 'constants.' I believe the closest thing to this is indeed Kohana's config API. So, if you wanted to make templates aware of some site-wide constant like your site name, that's a great thing to use the config API for.
To accomplish this, you'll need to create a config file under your /config folder, probably in the /application directory. What you call it isn't very important, but since it contains site information, let's call it site.php.
To quickly get going, here is what you'll want to have in that file:
<?php defined('SYSPATH') or die('No direct script access.');
return array(
// Your site name!
'name' => 'Oh me, Oh my',
);
Now, you can bring this in to a template by doing something like:
A better way to do this (using dumb templating) would be to assign this as a template variable in your Controller. So, assuming you have some default controller set up, the code would be:
public function action_index() {
$this->template->site_name = Kohana::config('site.name');
}
And then your template would have something like this:
<title><?php echo $site_name; ?></title>
Kohana's config API is interesting because it is hierarchical, meaning you can override and merge new configuration values on top of existing config structures. When you call Kohana::config('site.name'), the engine looks through all the config files named site.php, runs all of those config files and merges the results in to an array. The application-level config files will overwrite modules, which will overwrite system, etc... Then, based on that result array, Kohana will attempt to find the 'name' key and return it.
Assuming you want global constants...the following worked well for me.
application/config/constants.php:
define('MY_COOL_CONSTANT', 'foo');
return array();
index.php:
Kohana::$config->load('constants');
MY_COOL_CONSTANT should then be available globally.

Looking for ideas/solutions to manage application configuration settings

I'm building an MVC framework in PHP that will need to set a number of default configuration variables/constants. Example config vars would be where to save log files, whether to log queries, Doctrine settings, amongst many others. Because I want developers to be able to create new projects with minimal fuss, these config vars should have default values. However to make this framework truly useful, I need them to be able to override these default values either in a project bootstrap file, or from within a controller or model. I would love to use constants, but they cannot be overwritten. I feel as though there must be a simple solution that I just don't see (perhaps a design pattern?). Any advice would be greatly appreciated, thanks.
In a situation like this, I would probably :
Create a class that deal with everything configuration-related
That class would contain methods to get/set configurations options ; whatever your application needs
It would also define default values, when suitable
Use a .ini or .xml file, in which configuration values can be re-defined
When instanciating the class :
You already have the default values
You parse the .ini or .xml file
Each value defined in that configuration file is used to override the corresponding default value that what defined in the class.
A solution a bit more complex, but maybe better, might be to :
Still have that configuration class, but not use it to store any default values
Have one .ini or .xml file to store default values
Have one .ini or .xml file in which people can override the values defined in the default one
Load the file containing the default values, and then the one containing the specific ones
Advantages of this solution are :
No configuration value stored in a PHP class
All configuration options that can be overriden are already defined in a .ini / .xml file, which means people just have to copy/paste a line to their specific file to override : no need to go take a look at the PHP class and think "how do I translate this to a config file ?"
A couple more notes :
You might want to use some kind of caching-mecanism, to not re-parse the files at each request
Zend_Config and Zend_Config_Ini might be helpful ; even if you don't use those, as you are writing your own framework, you might want to take a look at what they do -- If I remember correctly, Zend_Config_Ini allows for hierarchy and inheritance in .ini files
Have fun!
I'd suggest using several ini files: a default.ini, and then as much override.ini-s as you need. Then simply load them with parse_ini_file() and merge into one config with array_merge(). Quick and simple.
Here's the design pattern I would use. I would create a simple class to facilitate it:
class Configuration {
String get($key) {...}
String set($key, $value) {...}
}
Initial implementation could all be hard-coded with default values. Later, though, you could slip in the reading of a server and/or project specific configuration file. It would give you flexibility to add as needed.
(I also noticed that the php.ini configurations seem to have the behavior you want, but I don't see how you leverage that system directly.)
This question can come with a wide variety of answers. My personal recomendation would be to store values into SQLite and have a seperate script to access and change those values. For other way continue to read.
This is pretty simple depending on how object oriented you want to be and how simplified you want to make things for your users. Your install instructions could simply instruct users to edit a file directly. In which case you could simply instruct users to edit a file of constants directly.
Most applications that follow this route implement it with detail explination
<?php
/**
* Global application configuration
*/
class AWConfig {
/**
* true or false
* If the is set to true debug messages will be added to the application logs
*/
public $DEBUG_MODE = true;
/**
* Path to Station database
* ex (/homepages/26/3/htdocs/databases/stations.db)
*/
public $DB_STATION = '/homepages/26/3/htdocs/databases/stations.db';
/**
* Path to logs database
* ex (/homepages/26/3/htdocs/databases/stations.db)
*/
public $DB_LOGS = '/homepages/26/d175338743/htdocs/weather/dev/metrics/beta2/databases/metriclogs.db';
/**** DO NOT EDIT BELOW THIS LINE *****/
public $LIST_STATION_LIMIT = 10;
public $MAX_COMPARE = 6;
}
?>
If you want to hide these details from the user than an initial setup script would be best that would prompt user for details and write a file (config.php, config.ini, config.xml, or to a database) the settings they chose. Then a different script to edit in the future. Good example would be Joomla CMS.

Templates in PHP, and the best way to notify the application that one exists?

I'm using CodeIgniter, and will likely use their template library as I want to keep things extremely simple to use. The content for the template variables will come from the database, but I want the business admins to know what content areas are available. Basically the names of the parameters when they choose a specific template. For instance, Joomla uses an extra XML file that defines each area, whereas Wordpress uses comments within a page template to inform the system that the PHP file is a template. I like the Joomla approach because you don't have to parse the PHP file to find the areas, but I like the Wordpress approach because you don't have an extra XML file associated with every template. Are there other approaches that I'm missing?
I think the nicest way would be to add a small hack to the template parser class. The code looks quite readable and clean in system/libraries/Parser.php. You could insert a hook in that class that can be used to keep track of the variables. I don't know, if it works, but here's a snippet:
class CI_Parser {
var $varCallback;
function setVarCallback($callbackFunction) {
$this->varCallback = $callbackFunction;
}
...
function _parse_single(...) {
$callback = $this->varCallback;
$callback($key);
}
...
//Somewhere in your code
function storeVarName($variableName) {
// Persist the variable name wherever you want here
}
$this->parser->setVarCallback('storeVarName');
You could do this directly in the controller:
// in the controller
print_r($data);
$this->load->view("main", $data);
Or a little more rudimentary, but you could pass to the template a PHP array of variables (or an object):
// in the controller
$data = array();
$data["namespace"] = array(
"title" => "My website",
"posts" => array("hi", "something else")
);
$this->load->view("main", $data);
And then in the view, have a flag to print_r the namespace to show all the vars available, so that business admins know exactly what to use.
// in the view
if(isset($namespace["showAllVars"])) print_r($namespace);
One option would be to call token_get_all on the PHP file (only when your business admins are loading it up), and parse the output of that.
The best approach, in my opinion, is to keep the variable definitions in another place (such as a database table, or a separate file). This will help with testing (i.e., a programmer can't just remove a tag and it's gone) and making sure things are still working as you move on with the application development in time.
Another advantage is that your application logic will be independent from the templating engine.
On a side note, if you expect a lot of traffic, you may consider using smarty instead. We have done extensive testing with most of the templating engines around and smarty is the fastest.

Categories