I'm trying to parse some items from a log of soap request XML and can't seem to figure out how to get to the innards of a SimpleXMLElement. Here's an example of the XML I'm using:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/" xmlns:ns1="http://fedex.com/ws/rate/v9">
<SOAP-ENV:Body>
<ns1:RateRequest>
<ns1:WebAuthenticationDetail>
<ns1:UserCredential>
<ns1:Key>aaaaaaaaaaa</ns1:Key>
<ns1:Password>aaaaaaaaaaaaaaaaaaa</ns1:Password>
</ns1:UserCredential>
</ns1:WebAuthenticationDetail>
<ns1:ClientDetail>
<ns1:AccountNumber>11111111</ns1:AccountNumber>
<ns1:MeterNumber>88888888</ns1:MeterNumber>
</ns1:ClientDetail>
<ns1:TransactionDetail>
<ns1:CustomerTransactionId>1</ns1:CustomerTransactionId>
</ns1:TransactionDetail>
<ns1:Version>
<ns1:ServiceId>crs</ns1:ServiceId>
<ns1:Major>9</ns1:Major>
<ns1:Intermediate>0</ns1:Intermediate>
<ns1:Minor>0</ns1:Minor>
</ns1:Version>
<ns1:ReturnTransitAndCommit>true</ns1:ReturnTransitAndCommit>
<ns1:RequestedShipment>
<ns1:ShipTimestamp>2013-08-06T12:39:26-04:00</ns1:ShipTimestamp>
<ns1:DropoffType>REGULAR_PICKUP</ns1:DropoffType>
<ns1:Shipper>
<ns1:AccountNumber>11111111</ns1:AccountNumber>
<ns1:Address>
<ns1:StreetLines>24 Seaview Blvd</ns1:StreetLines>
<ns1:City>Port Washington</ns1:City>
<ns1:StateOrProvinceCode>NY</ns1:StateOrProvinceCode>
<ns1:PostalCode>11050</ns1:PostalCode>
<ns1:CountryCode>US</ns1:CountryCode>
</ns1:Address>
</ns1:Shipper>
<ns1:Recipient>
<ns1:Address>
<ns1:StreetLines>1234 Fifth Street</ns1:StreetLines>
<ns1:City>Sixton</ns1:City>
<ns1:StateOrProvinceCode>AR</ns1:StateOrProvinceCode>
<ns1:PostalCode>72712</ns1:PostalCode>
<ns1:CountryCode>US</ns1:CountryCode>
</ns1:Address>
</ns1:Recipient>
<ns1:ShippingChargesPayment>
<ns1:Payor>
<ns1:AccountNumber>11111111</ns1:AccountNumber>
<ns1:CountryCode>US</ns1:CountryCode>
</ns1:Payor>
</ns1:ShippingChargesPayment>
<ns1:RateRequestTypes>ACCOUNT</ns1:RateRequestTypes>
<ns1:PackageCount>1</ns1:PackageCount>
<ns1:PackageDetail>INDIVIDUAL_PACKAGES</ns1:PackageDetail>
<ns1:RequestedPackageLineItems>
<ns1:Weight>
<ns1:Units>LB</ns1:Units>
<ns1:Value>14</ns1:Value>
</ns1:Weight>
<ns1:Dimensions>
<ns1:Length>20</ns1:Length>
<ns1:Width>20</ns1:Width>
<ns1:Height>9</ns1:Height>
<ns1:Units>IN</ns1:Units>
</ns1:Dimensions>
</ns1:RequestedPackageLineItems>
</ns1:RequestedShipment>
</ns1:RateRequest>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
I'm trying to get out values like the CountryCode, PostalCode Weight->Value and all of the Dimensions but the namespaces are confusing me. Any time I parse it, and look in the debugger all I see for any given variable is {SimpleXMLElement} [0] yet some will show output with ->asXML() but most of my attempts to access data either error out, return false, or return another {SimpleXMLElement} [0]. I just want the string/value for these nodes!
The following for example, outputs absolutely nothing:
$fReq = simplexml_load_string($xmlRequest);
$fReq->registerXPathNamespace('ns1', 'http://fedex.com/ws/rate/v9');
$ns = $fReq->getNameSpaces(true);
$rr = $fReq->children($ns['ns1']);
echo $rr->asXML()."\n";
I prefer using XMLReader: http://us3.php.net/manual/en/class.xmlreader.php
This is a example form PHP with small modification for match your requirements:
function xmlParse($content,$wrapperName,$callback,$limit=NULL){
$xml = new XMLReader();
$xml->xml($content);
$n=0;
$x=0;
while($xml->read()){
if($xml->nodeType==XMLReader::ELEMENT && $xml->name == $wrapperName){
while($xml->read() && $xml->name != $wrapperName){
if($xml->nodeType==XMLReader::ELEMENT){
$name = $xml->name;
$xml->read();
$value = $xml->value;
if(preg_match("/[^\s]/",$value)){
$subarray[$name] = $value;
}
}
}
if($limit==NULL || $x<$limit){
if($callback($subarray)){
$x++;
}
unset($subarray);
}
$n++;
}
}
$xml->close();
}
xmlParse($test,'SOAP-ENV:Envelope','callback');
function callback($array){
var_dump($array);
}
Just execute this with you XML and will return
Array
(
[ns1:Key] => aaaaaaaaaaa
[ns1:Password] => aaaaaaaaaaaaaaaaaaa
[ns1:AccountNumber] => 11111111
[ns1:MeterNumber] => 88888888
[ns1:CustomerTransactionId] => 1
[ns1:ServiceId] => crs
[ns1:Major] => 9
[ns1:Intermediate] => 0
[ns1:Minor] => 0
[ns1:ReturnTransitAndCommit] => true
[ns1:ShipTimestamp] => 2013-08-06T12:39:26-04:00
[ns1:DropoffType] => REGULAR_PICKUP
[ns1:StreetLines] => 1234 Fifth Street
[ns1:City] => Sixton
[ns1:StateOrProvinceCode] => AR
[ns1:PostalCode] => 72712
[ns1:CountryCode] => US
[ns1:RateRequestTypes] => ACCOUNT
[ns1:PackageCount] => 1
[ns1:PackageDetail] => INDIVIDUAL_PACKAGES
[ns1:Units] => IN
[ns1:Value] => 14
[ns1:Length] => 20
[ns1:Width] => 20
[ns1:Height] => 9
)
Regards
You don't need to call registerXPathNamespace unless you're using XPath. You do, however, need to traverse through the SOAP Body element, which means you need to think about two namespaces, not just one.
It's also a good idea not to rely on namespace prefixes like ns1 staying the same in the future; the part that's guaranteed is the actual URI in the xmlns attribute. One way to make this more readable is to define constants for the XML namespaces used in your application, and pass those to the ->children() and ->attributes() methods when necessary.
Note also that ->children() "selects" a namespace until further notice, so once you've selected the Fedex namespace and traversed to the RateRequest node, you can just access elements as though namespaces weren't an issue (since everything below that in this document is in that same namespace).
Here's a completed example showing how this might look (see a live demo here).
// Give your own aliases to namespaces, don't rely on the XML always having the same ones
define('NS_SOAP', 'http://schemas.xmlsoap.org/soap/envelope/');
define('NS_FEDEX_RATE', 'http://fedex.com/ws/rate/v9');
// Parse the XML
$sx = simplexml_load_string($xml_string);
// $sx now represents the <SOAP-ENV:Envelope> element
// Traverse through the SOAP Body
$sx_soap_body = $sx->children(NS_SOAP)->Body;
// Now "switch" to the Fedex namespace, and start with the RateRequest node
$sx_rate_request = $sx_soap_body->children(NS_FEDEX_RATE)->RateRequest;
// Now traverse as normal, e.g. to the Recipient's CountryCode
// (the string cast isn't necessary for echo, but is a good habit to get into)
echo (string)$sx_rate_request->RequestedShipment->Recipient->Address->CountryCode;
Related
I have a Curl response with Soap XML data.
<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/><SOAP-ENV:Body><ns2:GetAccountMovementsResponseIo xmlns:ns2="http://www.mygemini.com/schemas/mygemini">
<ns2:result>
<ns2:pager>
<ns2:pageIndex>0</ns2:pageIndex>
<ns2:pageSize>700</ns2:pageSize>
</ns2:pager>
<ns2:totalCount>3</ns2:totalCount>
</ns2:result>
<ns2:accountMovement>
<ns2:movementId>002147575330.2</ns2:movementId>
<ns2:paymentId>95694091</ns2:paymentId>
<ns2:externalPaymentId>2147575330</ns2:externalPaymentId>
<ns2:debitCredit>1</ns2:debitCredit>
<ns2:valueDate>2018-12-13T00:00:00+04:00</ns2:valueDate>
<ns2:description>გადარიცხვა პირად ანგარიშზე</ns2:description>
<ns2:amount>
<ns2:amount>10000</ns2:amount>
<ns2:currency>GEL</ns2:currency>
</ns2:amount>
<ns2:accountNumber>GE44TB7142536020100005</ns2:accountNumber>
<ns2:accountName>კლიენტი:1425</ns2:accountName>
<ns2:additionalInformation>კლიენტი:1425, 123456786, TBCBGE22, GE17TB7142536020100006</ns2:additionalInformation>
<ns2:documentDate>2018-12-13T00:00:00+04:00</ns2:documentDate>
<ns2:documentNumber>1544698824</ns2:documentNumber>
<ns2:partnerAccountNumber>GE17TB7142536020100006</ns2:partnerAccountNumber>
<ns2:partnerName>კლიენტი:1425, 123456786</ns2:partnerName>
<ns2:partnerTaxCode>123456786</ns2:partnerTaxCode>
<ns2:partnerBankCode>TBCBGE22</ns2:partnerBankCode>
<ns2:partnerBank>სს თიბისი ბანკი</ns2:partnerBank>
<ns2:taxpayerCode>123456786</ns2:taxpayerCode>
<ns2:taxpayerName>კლიენტი:1425, 123456786</ns2:taxpayerName>
<ns2:operationCode>GII</ns2:operationCode>
<ns2:partnerDocumentType>0</ns2:partnerDocumentType>
<ns2:statusCode>3</ns2:statusCode>
<ns2:transactionType>1</ns2:transactionType>
</ns2:accountMovement>
<ns2:accountMovement>
<ns2:movementId>002147575330.1</ns2:movementId>
<ns2:paymentId>95694091</ns2:paymentId>
<ns2:externalPaymentId>2147575330</ns2:externalPaymentId>
<ns2:debitCredit>0</ns2:debitCredit>
<ns2:valueDate>2018-12-13T00:00:00+04:00</ns2:valueDate>
<ns2:description>გადარიცხვა პირად ანგარიშზე</ns2:description>
<ns2:amount>
<ns2:amount>10000</ns2:amount>
<ns2:currency>GEL</ns2:currency>
</ns2:amount>
<ns2:accountNumber>GE17TB7142536020100006</ns2:accountNumber>
<ns2:accountName>კლიენტი:1425, 123456786</ns2:accountName>
<ns2:additionalInformation>კლიენტი:1425, TBCBGE22, GE44TB7142536020100005</ns2:additionalInformation>
<ns2:documentDate>2018-12-13T00:00:00+04:00</ns2:documentDate>
<ns2:documentNumber>1544698824</ns2:documentNumber>
<ns2:partnerAccountNumber>GE44TB7142536020100005</ns2:partnerAccountNumber>
<ns2:partnerName>კლიენტი:1425</ns2:partnerName>
<ns2:partnerTaxCode>123456786</ns2:partnerTaxCode>
<ns2:partnerBankCode>TBCBGE22</ns2:partnerBankCode>
<ns2:partnerBank>სს თიბისი ბანკი</ns2:partnerBank>
<ns2:taxpayerCode>123456786</ns2:taxpayerCode>
<ns2:taxpayerName>კლიენტი:1425, 123456786</ns2:taxpayerName>
<ns2:operationCode>GII</ns2:operationCode>
<ns2:partnerDocumentType>0</ns2:partnerDocumentType>
<ns2:statusCode>3</ns2:statusCode>
<ns2:transactionType>1</ns2:transactionType></ns2:accountMovement>
<ns2:accountMovement><ns2:movementId>002147575329.2</ns2:movementId>
<ns2:externalPaymentId>2147575329</ns2:externalPaymentId>
<ns2:debitCredit>1</ns2:debitCredit>
<ns2:valueDate>2018-12-13T00:00:00+04:00</ns2:valueDate>
<ns2:description>ანგარიშზე თანხის შეტანა</ns2:description><ns2:amount>
<ns2:amount>100000</ns2:amount><ns2:currency>GEL</ns2:currency></ns2:amount>
<ns2:accountNumber>GE17TB7142536020100006</ns2:accountNumber>
<ns2:accountName>კლიენტი:1425</ns2:accountName>
<ns2:additionalInformation>სახელი:3928462 გვარი3928462</ns2:additionalInformation>
<ns2:documentDate>2018-12-13T00:00:00+04:00</ns2:documentDate>
<ns2:documentNumber>63946130</ns2:documentNumber>
<ns2:partnerAccountNumber>GE78TB0000000000060000</ns2:partnerAccountNumber>
<ns2:partnerName>სახელი:3928462 გვარი3928462</ns2:partnerName>
<ns2:partnerTaxCode>00000000000</ns2:partnerTaxCode>
<ns2:partnerBankCode>TBCBGE22</ns2:partnerBankCode><ns2:partnerBank>ს.ს. „თიბისი ბანკი”</ns2:partnerBank>
<ns2:operationCode>01</ns2:operationCode>
<ns2:partnerPersonalNumber>00000000000</ns2:partnerPersonalNumber>
<ns2:partnerDocumentType>6</ns2:partnerDocumentType>
<ns2:partnerDocumentNumber>DC102086</ns2:partnerDocumentNumber>
<ns2:statusCode>3</ns2:statusCode>
<ns2:transactionType>20</ns2:transactionType>
</ns2:accountMovement>
</ns2:GetAccountMovementsResponseIo>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
I would like to get data inside tags one by one
<ns2:paymentId>, <ns2:externalPaymentId>, <ns2:debitCredit> etc.
Kindly note that this is dummy data of a bank statement, and in real life responses have multiple tags with the same name per each transaction. For example, if there are 11 transactions, there will be 11 <ns2:paymentId> tags and I need to get data one by one.
Using SimpleXML you can read the code and the data much easier. The only thing is that you need to respect the namespaces. So first register the ns2 namespace so that you can then you can fetch the <ns2:accountMovement> elements. The loop over these, but to access the child elements in the namespace, use children("http://www.mygemini.com/schemas/mygemini") to get them into the $data variable, then each access is via this (i.e. $data->paymentId)...
$xml = simplexml_load_string($xmlContent);
$xml->registerXPathNamespace("ns2", "http://www.mygemini.com/schemas/mygemini");
$movements = $xml->xpath("//ns2:GetAccountMovementsResponseIo/ns2:accountMovement");
foreach ( $movements as $accMove ) {
$data = $accMove->children("http://www.mygemini.com/schemas/mygemini");
echo "paymentId ->".$data->paymentId.PHP_EOL;
echo "externalPaymentId ->".$data->externalPaymentId.PHP_EOL;
echo "debitCredit ->".$data->debitCredit.PHP_EOL;
}
I'd like to parse a XML file which is generated by an application called Folker. It's an application to transcribe spoken text. Sometimes it saves the lines in a good format which can be parsed with SimpleXML but sometimes it doesn't.
This line is good:
<contribution speaker-reference="KU" start-reference="TLI_107" end-reference="TLI_109" parse-level="1">
<unparsed>ich überLEG mir das [nochma:l,]</unparsed>
</contribution>
This line is not:
<contribution speaker-reference="VK" start-reference="TLI_108" end-reference="TLI_111" parse-level="1">
<unparsed>[JA:_a; ]<time timepoint-reference="TLI_109"/>ja,<time timepoint-reference="TLI_110"/>also (.) wie [geSAGT;]</unparsed>
</contribution>
In the second line SimpleXML removes the tags which are inside the unparsed node.
How can I get SimpleXML to not remove these tags but parse it as deeper nodes or outputs as an object for example like this (just in JSON for better understanding):
"contribution": {
"speaker-reference": "VK",
"start-reference": "TLI_108",
"end-reference": "TLI_111",
"parse-level": "1",
"unparsed": {
"content": "[JA:_a; ]",
"time": {
[
"timepoint-reference": "TLI_109",
"content": "ja,"
],
[
"timepoint-reference": "TLI_110",
"content": "also (.) wie [geSAGT;]"
]
}
}
}
No, it does not remove them. This works flawlessly (interesting app btw):
<?php
$string = '<contribution speaker-reference="VK" start-reference="TLI_108" end-reference="TLI_111" parse-level="1">
<unparsed>[JA:_a; ]<time timepoint-reference="TLI_109"/>ja,<time timepoint-reference="TLI_110"/>also (.) wie [geSAGT;]</unparsed>
</contribution>';
$xml = simplexml_load_string($string);
$t = $xml->unparsed->time[0];
print_r($t->attributes());
?>
// output:
SimpleXMLElement Object
(
[#attributes] => Array
(
[timepoint-reference] => TLI_109
)
)
You can even iterate over them:
$times = $xml->unparsed->children();
foreach ($times as $t) {
$attributes = $t->attributes());
// do sth. useful with them afterwards
}
Hint: Assumingly, you were trying print_r() or var_dump() on the xml tree. This sometimes gives back opaque results as most of the magic happens behind the scenes. Better use echo $xml->asXML(); to see the actual XML string.
I parsing scores from http://sports.in.msn.com/football-world-cup-2014/south-africa-v-brazil/1597383
I able to parse all the attributes. But I can't able to parse the time.
I Used
$homepages = file_get_html("http://sports.in.msn.com/football-world-cup-2014/south-africa-v-brazil/1597383");
$teama = $homepages->find('span[id="clock"]');
Kindly help me
Since the that particular site is loading the values dynamically (thru AJAX request), you cant really parse the value upon initial load.
<span id="clock"></span> // this tends to be empty initial load
Normal scrapping:
$homepages = file_get_contents("http://sports.in.msn.com/football-world-cup-2014/south-africa-v-brazil/1597383");
$doc = new DOMDocument();
#$doc->loadHTML($homepages);
$xpath = new DOMXPath($doc);
$query = $xpath->query("//span[#id='clock']");
foreach($query as $value) {
echo $value->nodeValue; // the traversal is correct, but this will be empty
}
My suggestion is instead of scraping it, you will need to have to access it thru a request also, since it is a time (of course, as the match goes on this will change and change until the game has ended). Or you can also use their request.
$url = 'http://sports.in.msn.com/liveplayajax/SOCCERMATCH/match/gsm/en-in/1597383';
$contents = file_get_contents($url);
$data = json_decode($contents, true);
echo '<pre>';
print_r($data);
echo '</pre>';
Should yield something like (a part of it actually):
[2] => Array
(
[Code] =>
[CommentId] => -1119368663
[CommentType] => manual
[Description] => FULL-TIME: South Africa 0-5 Brazil.
[Min] => 90'
[MinExtra] => (+3)
[View] =>
[ViewHint] =>
[ViewIndex] => 0
[EditKey] =>
[TrackingValues] =>
[AopValue] =>
)
You should get the 90' by using foreach. Consider this example:
foreach($data['Commentary']['CommentaryItems'] as $key => $value) {
if(stripos($value['Description'], 'FULL-TIME') !== false) {
echo $value['Min'];
break;
}
}
Should print: 90'
I am parsing a SVG file using SimpleXMLElement in PHP. The SVG file is carefully constructed in Adobe Illustrator follow a layer format that I am attempted to dissect.
Consider this code:
// Create an XML object out of the SVG
$svg = new SimpleXMLElement('floorplan.svg', null, true);
// Register the SVG namespace
$svg->registerXPathNamespace('svg', 'http://www.w3.org/2000/svg');
// Get the normal floorplan layer
$normal = $svg->xpath('svg:g[#id="Normal"]');
// If the normal layer has content, continue
if(count($normal) > 0) {
// If there are floors, continue
if(count($normal[0]->g > 0)) {
// Loop through each floor
foreach($normal[0]->g as $floor) {
// Declare the namespace for the floor
$floor->registerXPathNamespace('svg', 'http://www.w3.org/2000/svg');
// Select the base floorplan
$floorsvg = $floor->xpath('svg:g[#id="Base"]')[0];
var_dump($floorsvg);
echo $floorsvg->asXML(); // THIS CAUSES THE ERROR
}
}
}
When I do a var_dump on $floorsvg, it is declaring it is a SimpleXMLElement object:
object(SimpleXMLElement)[9]
public '#attributes' =>
array (size=1)
'id' => string 'Base' (length=4)
public 'g' =>
array (size=859)
0 => ...
However, when I run asXML() on the object, I am presented with the following PHP error:
PHP Fatal error: Call to a member function asXML() on a non-object
I'm uncertain why asXML() is failing, considering it is an object. Can anyone shed any light on why this problem is occurring and what I might try to remedy it?
EDIT: Adding an echo $normal->asXML(); up above results in the same error. It seems like xpath is causing the object to become malformed somehow.
EDIT 2: The SVG file being parsed can be seen here: http://pastebin.com/zK1yRFA7
There are a few issues. Your code assumes that:
$floor->xpath('svg:g[#id="Base"]')
Will return an array with at least 1 element. The <g id="Second_Floor"> element does not contain any child elements that will be matched by that XPath expression, so trying to access element 0 of an empty array will give you the error you are seeing.
Adding a simple guard expression:
// Select the base floorplan
$floorsvg = $floor->xpath('svg:g[#id="Base"]')
if (count($floorsvg) > 0) {
echo $floorsvg[0]->asXML();
}
Will resolve that. Secondly, you have some misplaced parentheses in this line:
if(count($normal[0]->g > 0)) {
It should be:
if(count($normal[0]->g) > 0) {
Appears to be just a simple typo and doesn't appear to affect the outcome of this particular script one way or another.
I'm building my own personal CMS right now with PHP and MySql and I'm not sure of the best way to store site-wide variables such as the site name. What would be the proper way? (If you could provide a brief explanation that would be really nice too. ;)
EDIT: The variables would need to be editable from within the CMS.
In my opinion the best way is to store it in a config file (I use .ini files, but you could easily use a file like below).
I prefer this to storing it in a MySQL database, as it allows you to still get variables (like site name, or admin email address) even if the database is down
<?php
define('SITE_NAME','My CMS');
define('SITE_URL','http://www.example.com');
define('ADMIN_EMAIL','admin#example.com');
?>
EDIT:
Create a table like this
id key value
-------------------
1 name My Cms
2 url http://www.example.com
And access it like this (at the top of every page)
<?php
$config = array();
$query = mysql_query('SELECT * FROM config');
while ($row = mysql_fetch_row($query)) {
$key = $row['key'];
$value = $row['value'];
$config[$key] = $value;
}
echo $config['name'];
?>
There is no "best" sollution for all purposes.
Here are some examples how you can do this:
Simple PHP file:
This sollution is very simple but not very flexible:
you just 'define' constants:
define('SITE_NAME', 'all about Foo');
define ('ADMIN_NAME', 'The Dude');
define ('ADMIN_MAIL', 'dude#foo.com');
Pro: very very simple.
Cons: changes require that you edit the code. Only flat keys (no tree/registry)
ini File
PHP comes with functions to parse ini files. Here is an example rom the php manual:
; This is a sample configuration file
; Comments start with ';', as in php.ini
[first_section]
one = 1
five = 5
animal = BIRD
[second_section]
path = "/usr/local/bin"
URL = "http://www.example.com/~username"
[third_section]
phpversion[] = "5.0"
phpversion[] = "5.1"
phpversion[] = "5.2"
phpversion[] = "5.3"
you can parse this in a multi dimensional array:
$ini_array = parse_ini_file("sample.ini", true);
print_r($ini_array);
Will output:
Array
(
[first_section] => Array
(
[one] => 1
[five] => 5
[animal] => Dodo bird
)
[second_section] => Array
(
[path] => /usr/local/bin
[URL] => http://www.example.com/~username
)
[third_section] => Array
(
[phpversion] => Array
(
[0] => 5.0
[1] => 5.1
[2] => 5.2
[3] => 5.3
)
)
)
Pros: lexible. A well known standart syntax.
Cons: Hard to edit in backend
See: http://php.net/manual/de/function.parse-ini-file.php
Simple SQL
Another simple aproach, but this uses a database to store the conig keys.
The table structure is:
config{config_name UNIQUE KEY VARCHAR[64] ; config_value VARCHAR[128]}
This is only pseudo code and i you need more information about PHP and SQL feel free to google it.
SQL Tree
Allows you to create a tree like structure. To archive this you use the same table structure but include '/' in your key names:
admin/name | 'The Dude'
admin/mail | 'dude#foo.com'
Then you load your COMPLETE config in an array and parse it:
function parseRawConfig($rawConfig){
$result = array();
foreach($rawConfig as $key => $value){
$nodeNames = explode('/',$key);
$nodeCount = count($nodes);
$node = $result;
for($i=1;$i<$nodeCount;$i++){
if(!array_key_exists($nodeNames[$i],$node)){
$node[$nodeNames[$i]] = array();
}
}
$node[$nodeNames[$nodeCount-1]] = $value;
}
return $result;
}
Then you can access your keys like this:
echo $config['admin']['mail'];
This makes it easy to generate a nice tree view for your backend, but to save the changes you will have to 'reconstruct' the original path.
Pro: structured hierarchical data.
Con: Complicated, hard to implement, requires db connection
XML
Write all your conig settings in a xml file.
You can either use a app specific xml or a generic registry like style:
<cmsConf>
<site>all about foo</site>
<admin>
<name>The Dude</name>
<mail>dude#foo.com</mail>
</admin>
</cmsConf>
<reg>
<key name="site">all about foo</key>
<node name="admin">
<key name="name">The Dude</key>
<key name="mail">dude#foo.com</key>
</node>
</reg>
PHP provides plenty of classes and functions for reading/writting xml, and using xml makes it really easy to create interfaces to other applications.
The pros/cons of xml are a huge topic. To huge to sum them up in a few sentences.
IMPORTANT
These are just some very simple examples and if you choose one I recommend you dig deeper into the topic!
My fav is XML ;)
a configuration file in whatever format you like.
I usually create one table with all config variables. Every column will get a clear name of what its setting means. Then I use the following query to store it in a single array for easy use.
<?php
$result = mysql_query("SELECT * FROM configtable WHERE siteID=$siteID LIMIT 1");
$siteConfig = mysql_fetch_assoc($result);
?>
This way it is very easy to add new config parameters, you only need to add a column to the configtable and you can directly use the value in your site. Plus you only have one variable so an accidental reuse of a config variable wont happen.