Cphalcon: Config Adapter Ini

Created on 8 Jun 2016  路  11Comments  路  Source: phalcon/cphalcon

In Line 65:
let iniConfig = parse_ini_file(filePath, true);

INI_SCANNER_TYPED preserves the data types when reading ini strings.

Example Config Ini File:

[ttl]
zero    =   0
min     =   60

Without INI_SCANNER_TYPED:

["ttl"]=>
  array(6) {
    ["zero"]=>
    string(1) "0"
    ["min"]=>
    string(2) "60"
  }

With INI_SCANNER_TYPED:

  ["ttl"]=>
  array(6) {
    ["zero"]=>
    int(0)
    ["min"]=>
    int(60)
  }

All 11 comments

Could you please send PR?

INI_SCANNER_TYPED has added since PHP 5.6.1, so for an older PHP versions will be different behaviour. You can do it with INI_SCANNER_RAW as is in the ice.

i've already checked the INI_SCANNER_RAW but the problem is still the same without INI_SCANNER_TYPED.
i鈥檒l try to find out another solution.

You have to compare INI_SCANNER_NORMAL with INI_SCANNER_RAW and cast manually eg. like in ice's ini:

namespace Ice\Config;

use Ice\Config;
use Ice\Exception;

/**
 * Adapter for get config from ini files.
 *
 * @package     Ice/Config
 * @category    Configuration
 * @author      Ice Team
 * @copyright   (c) 2014-2015 Ice Team
 * @license     http://iceframework.org/license
 */
class Ini extends Config
{

    /**
     * Config ini constructor.
     *
     * @param string file Path to the ini file
     */
    public function __construct(var data = null)
    {
        var ini, raw;

        if typeof data != "string" {
            throw new Exception("The file path must be a string");
        }

        let ini = parse_ini_file(data, true),
            raw = parse_ini_file(data, true, INI_SCANNER_RAW),
            data = this->map(ini, raw);

        parent::__construct(data);
    }

    /**
     * We have to cast values manually because parse_ini_file() has a poor implementation.
     *
     * @param mixed ini The array casted by `parse_ini_file`
     * @param mixed raw The same array but with raw strings
     * @return mixed
     */
    private function cast(ini, raw)
    {
        if typeof ini == "string" {
            // Decode true
            if ini == "1" && (raw === "true" || raw === "yes" || raw === "on") {
                return true;
            }

            // Decode false
            if ini === "" && (raw === "false" || raw === "no" || raw === "off") {
                return false;
            }

            // Decode null
            if ini === "" && raw === "null" {
                return null;
            }

            // Decode float/int
            if is_numeric(ini) {
                if preg_match("/[.]+/", ini) {
                    return (double) ini;
                } else {
                    return (int) ini;
                }
            }
        }
        return ini;
    }

    /**
     * Map the array recursively.
     *
     * @param array ini
     * @param array raw
     * @return array
     */
    private function map(ini, raw)
    {
        var key, value, data = [];

        for key, value in ini {
            if typeof value == "array" {
                let data[key] = this->map(value, raw[key]);
            } else {
                let data[key] = this->cast(value, raw[key]);
            }
        }
        return data;
    }
}

Ahhhh i read the code now, Gud :)

This would work only on PHP 5.6.1+
So for many productions it won't be available.

As of PHP 5.6.1 can also be specified as INI_SCANNER_TYPED. In this mode boolean, null and integer types are preserved when possible. String values "true", "on" and "yes" are converted to TRUE. "false", "off", "no" and "none" are considered FALSE. "null" is converted to NULL in typed mode. Also, all numeric strings are converted to integer type if it is possible.

We can backport this feature from PHP 5.6 source to the Zephir

Fixed in the 2.1.x branch.

Was this page helpful?
0 / 5 - 0 ratings