Network Security Internet Technology Development Database Servers Mobile Phone Android Software Apple Software Computer Software News IT Information

In addition to Weibo, there is also WeChat

Please pay attention

WeChat public account

Shulou

What are the ways to build configurable PHP applications

2025-04-03 Update From: SLTechnology News&Howtos shulou NAV: SLTechnology News&Howtos > Development >

Share

Shulou(Shulou.com)06/03 Report--

This article focuses on "what are the ways to build configurable PHP applications". Interested friends may wish to take a look. The method introduced in this paper is simple, fast and practical. Let the editor take you to learn what are the ways to build configurable PHP applications.

Use INI files for configuration

PHP has built-in support for configuration files. This is achieved through an initialization file (INI) mechanism such as the php.ini file, which defines constants such as database connection timeout or how the session is stored in the php.ini file. If you prefer, you can customize the configuration for the application in this php.ini file. To illustrate, I added the following lines of code to the php.ini file.

Myapptempdir=foo

Then I wrote a small PHP script to read the configuration item, as shown in listing 1.

List 1.ini1.php

Functionget_template_directory ()

{

$v=get_cfg_var ("myapptempdir")

Return ($v==null)? "tempdir": $v

}

Echo (get_template_directory (). "\ n")

? >

When you run this code on the command line, you get the following results:

% phpini1.php

Foo

%

great. But why can't you use the standard INI function to get the value of the myapptempdir configuration item? I studied it and found that in most cases, custom configuration items cannot be obtained using these methods. However, you can access it using the get_cfg_var function.

To make this method easier, encapsulate the access to the variable in a second function, which uses the configuration key name and a default value as parameters, as shown below.

List 2.ini2.php

Functionget_ini_value ($nrecoverdv)

{

$c=get_cfg_var ($n)

Return ($c==null)? $dv:$c

}

Functionget_template_directory ()

{

Returnget_ini_value ("myapptempdir", "tempdir")

}

This is a good summary of how to access INI files, so if you want to use a different mechanism or store the INI file in another location, you don't have to go to a lot of trouble to change a lot of functions.

I do not recommend using INI files as the configuration of your application for two reasons. First, while it is easier to read INI files, it is almost impossible to write INI files safely. So this is only suitable for read-only configuration items. Second, the php.ini file is shared across all applications on the server, so I don't think application-specific configuration items should be written in this file.

What do you need to know about INI files? The most important thing is how to reset the include path to add configuration items, as shown below.

List 3.ini3.php

Echo (ini_get ("include_path"). "\ n")

Ini_set ("include_path"

Ini_get ("include_path"). ":. / mylib")

Echo (ini_get ("include_path"). "\ n")

? >

In this case, I added my local mylib directory to the include path, so I was able to requirePHP files from that directory without adding the path to the require statement.

Configuration in PHP

A common alternative to storing configuration entries in an INI file is to use a simple PHP script to hold the data. The following is an example.

List 4.config.php

# Specifythelocationofthetemporarydirectory

#

$TEMPLATE_DIRECTORY= "tempdir"

? >

The code that uses this constant is shown below.

List 5.php.php

Require_once'config.php'

Functionget_template_directory ()

{

Global$TEMPLATE_DIRECTORY

Return$TEMPLATE_DIRECTORY

}

Echo (get_template_directory (). "\ n")

? >

The code first includes the configuration file (config.php), and then you can use these constants directly.

There are many advantages to using this technology. First of all, if someone is just browsing the config.php file, the page is blank. So you can put config.php in the same file and act as the root of your Web application. Second, it can be edited in any editor, and there are even syntax coloring and syntax checking functions in some editors.

The disadvantage of this technique is that it is a read-only technology like INI files. Extracting the data from this file is easy, but adjusting the data in the PHP file is difficult and, in some cases, impossible.

The following alternative shows how to write a configuration system that is both readable and writable in nature.

Text file

The previous two examples are appropriate for read-only configuration entries, but what about configuration parameters that are both read and write? First, take a look at the text configuration file in listing 6.

List 6.config.txt

# Myapplication'sconfigurationfile

Title=MyApp

TemplateDirectory=tempdir

This is the same file format as the INI file, but I wrote my own aids. To do this, I created my own Configuration class, as shown below.

List 7.text1.php

ClassConfiguration

{

Private$configFile='config.txt'

Private$items=array ()

Function__construct () {$this- > parse ();}

Function__get ($id) {return$this- > items [$id];}

Functionparse ()

{

$fh=fopen ($this- > configFile,'r')

While ($l=fgets ($fh))

{

If (preg_match ('/ ^ # /', $l) = = false)

{

Preg_match ('/ ^ (. *?) = (. *?) $/', $ljingle found)

$this- > items [$found [1]] = $found [2]

}

}

Fclose ($fh)

}

}

$c=newConfiguration ()

Echo ($c-> TemplateDirectory. "\ n")

? >

The code first creates a Configuration object. The constructor then reads the config.txt and sets the local variable $items with the parsed contents of the file.

The script then looks for TemplateDirectory, which is not defined directly in the object. Therefore, the magic _ _ get method is called with $id set to 'TemplateDirectory', and the _ _ get method returns the value in the $items array for that key.

This _ _ get method is specific to the PHPV5 environment, so this script must be run under PHPV5. In fact, all the scripts in this article need to be run under PHPV5.

When you run this script on the command line, you can see the following results:

% phptext1.php

Tempdir

%

As expected, the object reads the config.txt file and then gets the correct value for the TemplateDirectory configuration item.

But what should I do about setting a configuration value? You can get this functionality by creating a new method and some new test code in this class, as shown below.

List 8.text2.php

ClassConfiguration

{

...

Function__get ($id) {return$this- > items [$id];}

Function__set ($id,$v) {$this- > items [$id] = $v;}

Functionparse () {...}

}

$c=newConfiguration ()

Echo ($c-> TemplateDirectory. "\ n")

$c-> TemplateDirectory='foobar'

Echo ($c-> TemplateDirectory. "\ n")

? >

Now you have a _ _ set function, which is the cousin of the _ _ get function. This function does not get a value for a member variable, but is called when you want to set a member variable. The test code at the bottom sets the value and prints the new value.

Here is what happens when you run this code on the command line:

% phptext2.php

Tempdir

Foobar

%

Great! But how can it be stored in a file to fix the change? To do this, you need to write the file and read it. The new function used to write the file is shown below.

List 9.text3.php

ClassConfiguration

{

...

Functionsave ()

{

$nf=''

$fh=fopen ($this- > configFile,'r')

While ($l=fgets ($fh))

{

If (preg_match ('/ ^ # /', $l) = = false)

{

Preg_match ('/ ^ (. *?) = (. *?) $/', $ljingle found)

$nf.=$found [1]. "=". $this- > items [$found [1]]. "\ n"

}

Else

{

$nf.=$l

}

}

Fclose ($fh)

Copy ($this- > configFile,$this- > configFile.'.bak')

$fh=fopen ($this- > configFile,'w')

Fwrite ($fh,$nf)

Fclose ($fh)

}

}

$c=newConfiguration ()

Echo ($c-> TemplateDirectory. "\ n")

$c-> TemplateDirectory='foobar'

Echo ($c-> TemplateDirectory. "\ n")

C-> save ()

? >

The new save function manipulates config.txt cleverly. Instead of rewriting the file with just the updated configuration item (which removes comments), I read the file and flexibly rewrite the contents of the $items array. In this case, the comments in the file are retained.

Run the script on the command line and output the contents of the text configuration file, and you can see the following output.

Listing 10. Save function output

% phptext3.php

Tempdir

Foobar

% catconfig.txt

# Myapplication'sconfigurationfile

Title=MyApp

TemplateDirectory=foobar

%

What are the ways to build configurable PHP applications

The original config.txt file is now updated with the new value.

XML profile

Although text files are easy to read and edit, they are not as popular as XML files. In addition, XML has many suitable editors that can understand tags, special symbol escapes, and so on. So what will the XML version of the configuration file look like? Listing 11 shows the configuration file in XML format.

List 11.config.xml

Tempdir

Listing 12 shows an updated version of the Configuration class that uses XML to load configuration settings.

List 12.xml1.php

ClassConfiguration

{

Private$configFile='config.xml'

Private$items=array ()

Function__construct () {$this- > parse ();}

Function__get ($id) {return$this- > items [$id];}

Functionparse ()

{

$doc=newDOMDocument ()

$doc- > load ($this- > configFile)

$cn=$doc- > getElementsByTagName ("config")

$nodes=$cn- > item (0)-> getElementsByTagName ("*")

Foreach ($nodesas$node)

$this- > items [$node- > nodeName] = $node- > nodeValue

}

}

$c=newConfiguration ()

Echo ($c-> TemplateDirectory. "\ n")

? >

It seems that XML has another benefit: the code is simpler and easier than the text version of the code. To save this XML, you need another version of the save function to save the results in XML format instead of text format.

List 13.xml2.php

...

Functionsave ()

{

$doc=newDOMDocument ()

$doc- > formatOutput=true

$ritual docking-> createElement ("config")

$doc- > appendChild ($r)

Foreach ($this- > itemsas$k= > $v)

{

$kn=$doc- > createElement ($k)

$kn- > appendChild ($doc- > createTextNode ($v))

$r-> appendChild ($kn)

}

Copy ($this- > configFile,$this- > configFile.'.bak')

$doc- > save ($this- > configFile)

}

...

This code creates a new XML document object model (DocumentObjectModel,DOM) and then saves all the data in the $items array to this model. After you have done this, use the save method to save the XML as a file.

Using the database

The final alternative is to use a database to hold the values of the configuration elements. The first step is to use a simple schema to store configuration data. Here is a simple pattern.

List 14.schema.sql

DROPTABLEIFEXISTSsettings

CREATETABLEsettings (

IdMEDIUMINTNOTNULLAUTO_INCREMENT

NameTEXT

ValueTEXT

PRIMARYKEY (id)

)

This requires some adjustments based on application requirements. For example, if you want configuration elements to be stored on a per-user basis, you need to add the user ID as an additional column.

To read and write data, I wrote the updated Configuration class shown in figure 15.

List 15.db1.php

Require_once ('DB.php')

$dsn='mysql://root:password@localhost/config'

$db=&DB::Connect ($dsn,array ())

If (PEAR::isError ($db)) {die ($db- > getMessage ());}

ClassConfiguration

{

Private$configFile='config.xml'

Private$items=array ()

Function__construct () {$this- > parse ();}

Function__get ($id) {return$this- > items [$id];}

Function__set ($id,$v)

{

Global$db

$this- > items [$id] = $v

$sth2=$db- > prepare ('DELETEFROMsettingsWHEREname=?')

$db- > execute ($sth2,$id)

If (PEAR::isError ($db)) {die ($db- > getMessage ());}

$sth3=$db- > prepare ('INSERTINTOsettings (id,name,value) VALUES')

$db- > execute ($sth3,array ($id,$v))

If (PEAR::isError ($db)) {die ($db- > getMessage ());}

}

Functionparse ()

{

Global$db

$doc=newDOMDocument ()

$doc- > load ($this- > configFile)

$cn=$doc- > getElementsByTagName ("config")

$nodes=$cn- > item (0)-> getElementsByTagName ("*")

Foreach ($nodesas$node)

$this- > items [$node- > nodeName] = $node- > nodeValue

$res=$db- > query ('SELECTname,valueFROMsettings')

If (PEAR::isError ($db)) {die ($db- > getMessage ());}

While ($res- > fetchInto ($row)) {

$this- > items [$row [0]] = $row [1]

}

}

}

$c=newConfiguration ()

Echo ($c-> TemplateDirectory. "\ n")

$c-> TemplateDirectory='newfoo'

Echo ($c-> TemplateDirectory. "\ n")

? >

This is actually a hybrid text / database solution. Take a closer look at the parse method. This class first reads the text file to get the initial value, then reads the database, and then updates the key to the latest value. After setting a value, the key is removed from the database and a new record with the updated value is added.

It is interesting to see how the Configuration class, which reads data from text files, XML, and databases, and maintains the same interface, works through multiple versions of this article. I encourage you to use interfaces with the same stability in your development. For the client of the object, it is not clear exactly how this work works. What matters is the contract between the object and the client.

At this point, I believe you have a better understanding of "what are the ways to build configurable PHP applications?" you might as well do it in practice. Here is the website, more related content can enter the relevant channels to inquire, follow us, continue to learn!

Welcome to subscribe "Shulou Technology Information " to get latest news, interesting things and hot topics in the IT industry, and controls the hottest and latest Internet news, technology news and IT industry trends.

Views: 0

*The comments in the above article only represent the author's personal views and do not represent the views and positions of this website. If you have more insights, please feel free to contribute and share.

Share To

Development

Wechat

© 2024 shulou.com SLNews company. All rights reserved.

12
Report