ini.php
1 <?php 2 // The description of the INI format 3 $INI_PATTERN = '/^[ \t]*([A-Z0-9_-]+)[ \t]*=[ \t]*((?:[^\r\n]|(?<=\\\\)[\r\n]{1,2})*)/m'; 4 5 // Global config dir absolute folder (no trailing slash) 6 $configdir = '/www/global/yotsuba/config'; 7 $yconfgdir = '/www/global/yotsuba/config'; 8 9 function parse_ini( $filename ) 10 { 11 global $INI_PATTERN; 12 $file = @file_get_contents( $filename ); 13 if( !$file ) return array(); 14 preg_match_all( $INI_PATTERN, $file, $matches, PREG_SET_ORDER ); 15 16 $ret = array(); 17 18 foreach( $matches as $match ) { 19 // replace backslash-newlines with newlines 20 $v = preg_replace( '|\\\\[\r\n]+|', "\n", $match[ 2 ] ); 21 $v = ltrim( $v ); 22 23 $ret[ $match[ 1 ] ] = $v; 24 } 25 26 return $ret; 27 } 28 29 function write_constants( $new ) 30 { 31 global $constants; 32 33 foreach( $new as $k => $v ) { 34 $constants[ $k ] = $v; // update the constants array 35 } 36 } 37 38 function load_ini( $filename ) 39 { 40 global $constants, $INI_PATTERN, $loaded_files; 41 $file = file_get_contents( $filename ); 42 preg_match_all( $INI_PATTERN, $file, $matches, PREG_SET_ORDER ); 43 44 foreach( $matches as $match ) { 45 // replace backslash-newlines with newlines 46 $match[ 2 ] = preg_replace( '|\\\\[\r\n]+|', "\n", $match[ 2 ] ); 47 $match[ 2 ] = ltrim( $match[ 2 ] ); 48 49 50 $constants[ $match[ 1 ] ] = $match[ 2 ]; // update the constants array 51 } 52 53 $loaded_files[$filename] = 1; 54 } 55 56 function special_callback( $matches ) 57 { 58 global $constants; 59 $val = str_replace( "!file ", "", $matches[ 1 ], $is_file ); 60 if( $is_file ) { 61 return @file_get_contents( $val ); 62 } 63 $val = str_replace( "!rand ", "", $matches[ 1 ], $is_rand ); 64 if( $is_rand ) { 65 $choices = explode( ",", $val ); 66 $val = array_rand( array_flip( $choices ) ); 67 $val = trim( $val ); 68 69 return $val; 70 } 71 72 return evaluate( $constants[ $val ] ); 73 } 74 75 function evaluate( $val ) 76 { 77 if( $val === 'yes' ) { 78 $val = true; 79 settype($val, "bool"); 80 } else if( $val === 'no' ) { 81 $val = false; 82 settype($val, "bool"); 83 } else { 84 $val = preg_replace_callback( '|\{\{(.*?)\}\}|', "special_callback", $val ); 85 86 // for numeric values, try to keep the PHP internal type as 'int' 87 if (ctype_digit($val)) { 88 settype($val, "int"); 89 } 90 } 91 92 return $val; 93 } 94 95 function finalize_constants() 96 { 97 global $constants; 98 99 $c2 = array(); 100 foreach( $constants as $key => $val ) { 101 $val = evaluate( $val ); 102 $c2[ $key ] = $val; 103 if( !defined( $key ) ) { 104 define( $key, $val ); 105 } 106 } 107 $constants = $c2; 108 } 109 110 $constants = array(); 111 $loaded_files = array(); 112 113 // quick wrapper function 114 function load_ini_file( $filename ) 115 { 116 global $loaded_files, $configdir, $constants; 117 if( strpos( $filename, '/' ) !== 0 ) $filename = "$configdir/$filename"; 118 119 if( in_array( $filename, $loaded_files ) ) return; 120 121 $constants = array(); 122 load_ini($filename); 123 finalize_constants(); 124 }