texto separar query parse multiexplode dividir cortar cadenas cadena array php parsing

query - separar cadenas de texto en php



Convierta la sintaxis de punto como "this.that.other" en una matriz multidimensional en PHP (7)

Aunque pasrse_ini_file () también puede traer una matriz multidimensional, presentaré una solución diferente. Zend_Config_Ini()

$conf = new Zend_COnfig_Ini("path/to/file.ini"); echo $conf -> one -> two -> three; // This is how easy it is to do so //prints one.two.three

Esta pregunta ya tiene una respuesta aquí:

Tal como lo implica el título, intento crear un analizador e intentar encontrar la solución óptima para convertir algo del espacio de nombres de punto en una matriz multidimensional de tal manera que

s1.t1.column.1 = size:33%

sería lo mismo que

$source[''s1''][''t1''][''column''][''1''] = ''size:33%'';


Encontré una solución que funcionó para mí en: Convert Flat PHP Array a Nested Array basado en Array Keys y como tenía una matriz basada en un archivo .ini con diferentes claves, realicé una pequeña modificación de esa secuencia de comandos y me funcionó.

Mi matriz se veía así:

[resources.db.adapter] => PDO_MYSQL [resources.db.params.host] => localhost [resources.db.params.dbname] => qwer [resources.db.params.username] => asdf ...

A petición, este es el código que describí que estaba funcionando para mí:

<?php echo "remove the exit :-)"; exit; $db_settings = parse_ini_file($_SERVER[''DOCUMENT_ROOT''].''/website/var/config/app.ini''); echo "<pre>"; print_r($db_settings); echo "</pre>"; $resources = array(); foreach ($db_settings as $path => $value) { $ancestors = explode(''.'', $path); set_nested_value($resources, $ancestors, $value); } echo "<pre>"; print_r($resources); echo "</pre>"; /** * Give it and array, and an array of parents, it will decent into the * nested arrays and set the value. */ function set_nested_value(array &$arr, array $ancestors, $value) { $current = &$arr; foreach ($ancestors as $key) { // To handle the original input, if an item is not an array, // replace it with an array with the value as the first item. if (!is_array($current)) { $current = array( $current); } if (!array_key_exists($key, $current)) { $current[$key] = array(); } $current = &$current[$key]; } $current = $value; }

Esta es la fuente del archivo .ini leído por parse_ini_file ():

Array ( [resources.db.adapter] => PDO_MYSQL [resources.db.params.host] => localhost [resources.db.params.dbname] => dbname [resources.db.params.username] => dbname_user [resources.db.params.password] => qwerqwerqwerqwer [resources.db.params.charset] => utf8 [externaldb.adapter] => PDO_MYSQL [externaldb.params.host] => localhost [externaldb.params.dbname] => dbname2 [externaldb.params.username] => dbname_user2 [externaldb.params.password] => qwerqwerwqerqerw [externaldb.params.charset] => latin1 )

Este es el resultado del código anterior:

Array ( [resources] => Array ( [db] => Array ( [adapter] => PDO_MYSQL [params] => Array ( [host] => localhost [dbname] => dbname [username] => dbname_user [password] => qwerqwerqwerqwer [charset] => utf8 ) ) ) [externaldb] => Array ( [adapter] => PDO_MYSQL [params] => Array ( [host] => localhost [dbname] => dbname2 [username] => dbname_user2 [password] => qwerqwerwqerqerw [charset] => latin1 ) ) )


Estoy bastante seguro de que está intentando hacer esto para almacenar algunos datos de configuración o similares.

Le sugiero encarecidamente que guarde un archivo como .ini y use la función parse_ini_file() para cambiar los datos de configuración en una matriz multidimensional. Tan simple como esto

$confArray = parse_ini_file("filename.ini"); var_dump($confArray);


FYI En Laravel tenemos una función auxiliar array_set() que se traduce en esta función

Método para almacenar en una matriz usando notación de puntos

/** * Set an array item to a given value using "dot" notation. * * If no key is given to the method, the entire array will be replaced. * * @param array $array * @param string $key * @param mixed $value * @return array */ public static function set(&$array, $key, $value) { if (is_null($key)) { return $array = $value; } $keys = explode(''.'', $key); while (count($keys) > 1) { $key = array_shift($keys); // If the key doesn''t exist at this depth, we will just create an empty array // to hold the next value, allowing us to create the arrays to hold final // values at the correct depth. Then we''ll keep digging into the array. if (! isset($array[$key]) || ! is_array($array[$key])) { $array[$key] = []; } $array = &$array[$key]; } $array[array_shift($keys)] = $value; return $array; }

Es simple como

$array = [''products'' => [''desk'' => [''price'' => 100]]]; array_set($array, ''products.desk.price'', 200); // [''products'' => [''desk'' => [''price'' => 200]]]

Puede verificarlo en los documentos

Si necesita obtener los datos usando notación de puntos, el proceso es un poco más largo, pero se sirve en una placa mediante array_get() que se traduce a esta función (en realidad, la fuente vinculada muestra toda la clase relacionada con la matriz auxiliar)

Método para leer desde una matriz usando notación de puntos

/** * Get an item from an array using "dot" notation. * * @param /ArrayAccess|array $array * @param string $key * @param mixed $default * @return mixed */ public static function get($array, $key, $default = null) { if (! static::accessible($array)) { return value($default); } if (is_null($key)) { return $array; } if (static::exists($array, $key)) { return $array[$key]; } if (strpos($key, ''.'') === false) { return $array[$key] ?? value($default); } foreach (explode(''.'', $key) as $segment) { if (static::accessible($array) && static::exists($array, $segment)) { $array = $array[$segment]; } else { return value($default); } } return $array; }

Como puede ver, utiliza dos submétodos, accessible() e exists()

/** * Determine whether the given value is array accessible. * * @param mixed $value * @return bool */ public static function accessible($value) { return is_array($value) || $value instanceof ArrayAccess; }

Y

/** * Determine if the given key exists in the provided array. * * @param /ArrayAccess|array $array * @param string|int $key * @return bool */ public static function exists($array, $key) { if ($array instanceof ArrayAccess) { return $array->offsetExists($key); } return array_key_exists($key, $array); }


Prueba este número ...

function assignArrayByPath(&$arr, $path, $value, $separator=''.'') { $keys = explode($separator, $path); foreach ($keys as $key) { $arr = &$arr[$key]; } $arr = $value; }

CodePad

Pasará por las teclas (delimitadas con . De forma predeterminada) para llegar a la propiedad final y luego realizará la asignación en el valor.

Si algunas de las claves no están presentes, se crean.


Rápido y sucio...

<?php $input = ''one.two.three = four''; list($key, $value) = explode(''='', $input); foreach (explode(''.'', $key) as $keyName) { if (false === isset($source)) { $source = array(); $sourceRef = &$source; } $keyName = trim($keyName); $sourceRef = &$sourceRef[$keyName]; } $sourceRef = $value; unset($sourceRef); var_dump($source);


Sugeriría usar dflydev/dot-access-data .

Si no está familiarizado con el uso de Composer, diríjase a https://getcomposer.org/ para obtener una introducción, de modo que pueda descargar y cargar automáticamente el paquete como dependencia para su proyecto.

Una vez que tenga el paquete, puede cargar una matriz multidimensional en un objeto de Datos:

use Dflydev/DotAccessData/Data; $data = new Data(array( ''s1'' => array( ''t1'' => array( ''column'' => array( ''1'' => ''size:33%'', ), ), ), );

Y acceda a los valores usando la notación de puntos:

$size = $username = $data->get(''s1.t1.column.1'');