Notes on INI files.



Unless the source code is freely available - and therefore the locations on INI files - there is no need to obfuscate or place INI files below DocumentRoot, as no one will know where they are. Otherwise, the .htaccess (or equivalent) to deny .ini files (or the config directory) is effective at preventing access.



And placing sensitive data in an INI file is just not a good idea in the first place. They are better off as defines (where, even if in a known location, can not seen):



<?php

define ( 'DB_NAME' , 'server_cms' );

define ( 'DB_USER' , 'server_user' );

define ( 'DB_PASS' , 'secretword' );

?>



Writing an array as an INI file is not so simple, and just wrapping values in double quotes will not always work. Consider:



key1 = true

key2 = ${PATH}"/foo"

key2a = CONSTANT"/foo"



Also, "If a value in the ini file contains any non-alphanumeric characters it needs to be enclosed in double-quotes" does not always hold.



For this works:



key2b = ${PATH}/foo



This is valid but fails to convert the constant:



key2c = CONSTANT/foo



This does convert the constant, there is just a space after it:



key2d = CONSTANT /foo



These characters are OK:



key3 = ` $ * % # @ { } < > / \ : , . ? + - _



For example:



key4 = The # is 100% of <value>.



And most bitwise operator, negation, logical not and parenthesis characters are used to calculate values:



key5 = ~1 | (!1 & 3) ^ -1



Which can be combined with constants and variables:



key6 = ${SHLVL} | PHP_VERSION & ${display_errors}



So, only values containing ( ) ! ^ | & ~ - ; = within a string need to be quoted, with either double- or single-quotes. As will strings containing reserved words.



Also, the concatenation operation is built-in:



key7 = "foo" 'bar' PHP_VERSION ${OS}



That result will have spaces before the constant and variable but not between the two quoted words. This eliminates the spaces:



key7a = "foo" 'bar'PHP_VERSION${OS}



But, punctuation fools the parsing:



key7b = "foo" 'bar',PHP_VERSION-${OS}



That needs to be (with spaces):



key7c = "foo" 'bar', PHP_VERSION - ${OS}



Or (without spaces):



key7d = "foo" 'bar,'PHP_VERSION'-'${OS}



And, of course, leading and trailing spaces in values are trimmed.



All of those were tested on PHP 7.0.13 and 5.6.18.



It would be cool for PHP to support shift and arithmetic operators:



key8 = (${SHLVL} * 2) >> 1



And cooler still, all logical operators; perhaps also comparison operators and the execution operator.



And way cool would be array support:



key9 = [ 1, 2, 3 ]



And globals and superglobals:



key10 = ${_SERVER["PHP_SELF"]}



Many people make their own INI parsers - I have a few versions - I think I'll try supporting the operators and arrays...



BUT, a "post parser" can convert such values as key9's and these:



key8a = '(${SHLVL} * 2) >> 1'

key10a = '${_SERVER["PHP_SELF"]}'

key11 = 'date("Y-m-d")'



The key9, key10a and key11 values can be converted via eval():



<?php

eval( "\$data['key9'] = { $data [ 'key9' ]} ;" );

eval( "\$data['key10a'] = \" { $data [ 'key10a' ]} \";" );

eval( "\$data['key11'] = { $data [ 'key11' ]} ;" );

?>



Values like key8's would be slightly trickier but hardly difficult.