info - php.ini example
Creando un archivo de configuración en PHP (10)
¡Utilizar un archivo INI es una solución flexible y potente! PHP tiene una función nativa para manejarlo correctamente. Por ejemplo, es posible crear un archivo INI como este:
[database]
db_name = mydatabase
db_user = myuser
db_password = mypassword
[application]
app_email = [email protected]
app_url = myapp.com
Así que lo único que debes hacer es llamar:
$ini = parse_ini_file(''app.ini'');
Luego puede acceder a las definiciones fácilmente usando la matriz $ini
.
echo $ini[''db_name'']; // mydatabase
echo $ini[''db_user'']; // myuser
echo $ini[''db_password'']; // mypassword
echo $ini[''app_email'']; // [email protected]
IMPORTANTE: por razones de seguridad, el archivo INI debe estar en una carpeta no pública
Quiero crear un archivo de configuración para mi proyecto PHP, pero no estoy seguro de cuál es la mejor manera de hacerlo.
Tengo 2 ideas hasta ahora.
1-uso variable
$config[''hostname''] = "localhost";
$config[''dbuser''] = "dbuser";
$config[''dbpassword''] = "dbpassword";
$config[''dbname''] = "dbname";
$config[''sitetitle''] = "sitetitle";
2-Use Const
define(''DB_NAME'', ''test'');
define(''DB_USER'', ''root'');
define(''DB_PASSWORD'', '''');
define(''DB_HOST'', ''localhost'');
define(''TITLE'', ''sitetitle'');
Base de datos de 3 usos
Usaré la configuración en clases, así que no estoy seguro de cuál sería la mejor manera o si hay una mejor.
Aquí está mi camino.
<?php
define(''DEBUG'',0);
define(''PRODUCTION'',1);
#development_mode : DEBUG / PRODUCTION
$development_mode = PRODUCTION;
#Website root path for links
$app_path = ''http://192.168.0.234/dealer/'';
#User interface files path
$ui_path = ''ui/'';
#Image gallery path
$gallery_path = ''ui/gallery/'';
$mysqlserver = "localhost";
$mysqluser = "root";
$mysqlpass = "";
$mysqldb = "dealer_plus";
?>
Cualquier duda por favor comenta.
Bueno, sería un poco difícil almacenar los datos de configuración de su base de datos en una base de datos, ¿no lo cree?
Pero, en realidad, esta es una pregunta bastante crítica porque cualquier estilo funciona realmente y es una cuestión de preferencia. Personalmente, prefiero una variable de configuración en lugar de constantes, generalmente porque no me gustan las cosas en el espacio global a menos que sea necesario. Ninguna de las funciones en mi base de código debería poder acceder fácilmente a la contraseña de mi base de datos (excepto la lógica de conexión de mi base de datos), así que la usaré allí y luego la destruiré.
Edición : para responder a su comentario, ninguno de los mecanismos de análisis sería el más rápido (ini, json, etc.), pero tampoco son las partes de su aplicación en las que realmente debería centrarse en la optimización, ya que la diferencia de velocidad Ser insignificante en archivos tan pequeños.
Definir hará que la constante esté disponible en todas partes de su clase sin necesidad de usar global, mientras que la variable requiere global en la clase, usaría DEFINIR. pero de nuevo, si los parámetros de db deberían cambiar durante la ejecución del programa, es posible que desee mantener la variable.
Estoy bastante sorprendido por la respuesta aceptada aquí, y el número de upvotes que ha cosechado. Con la excepción de la respuesta de Marcio Mazzucato, no se discuten los méritos / debilidades relativos de ninguno de los enfoques múltiples.
Las opciones que veo son:
Mecanismos basados en archivos
Estos requieren que su código busque en ubicaciones específicas para encontrar el archivo ini. Este es un problema difícil de resolver y que siempre surge en grandes aplicaciones de PHP. Sin embargo, es probable que necesite resolver el problema para encontrar el código PHP que se incorpora / reutiliza en el tiempo de ejecución.
Los enfoques comunes a esto son usar siempre directorios relativos, o buscar desde el directorio actual hacia arriba para encontrar un archivo nombrado exclusivamente en el directorio base de la aplicación.
Los formatos de archivo comunes utilizados para los archivos de configuración son código PHP, archivos con formato ini, JSON, XML, YAML y PHP serializado.
Código PHP
Esto proporciona una gran cantidad de flexibilidad para representar diferentes estructuras de datos, y (suponiendo que se procese a través de incluir o requerir) el código analizado estará disponible desde el caché de código de operación, lo que brinda un beneficio de rendimiento.
include_path proporciona un medio para abstraer las ubicaciones potenciales del archivo sin depender de código adicional.
Por otro lado, una de las razones principales para separar la configuración del código es separar las responsabilidades. Proporciona una ruta para inyectar código adicional en el tiempo de ejecución.
Si la configuración se crea a partir de una herramienta, puede ser posible validar los datos en la herramienta, pero no hay una función estándar para escapar de los datos para incrustarlos en el código PHP como existe para HTML, URL, declaraciones de MySQL, comandos de shell ... .
Datos serializados Esto es relativamente eficiente para pequeñas cantidades de configuración (hasta alrededor de 200 elementos) y permite el uso de cualquier estructura de datos PHP. Requiere muy poco código para crear / analizar el archivo de datos (por lo que puede dedicar sus esfuerzos a garantizar que el archivo solo se escriba con la autorización apropiada).
El escape del contenido escrito en el archivo se maneja automáticamente.
Dado que puede serializar objetos, crea una oportunidad para invocar código simplemente leyendo el archivo de configuración (el método mágico __wakeup).
Archivo estructurado
Al almacenarlo como un archivo INI según lo sugerido por Marcel o JSON o XML, también se proporciona una api simple para asignar el archivo a una estructura de datos PHP (y con la excepción de XML, para escapar de los datos y crear el archivo) mientras se elimina la invocación del código Vulnerabilidad al usar datos PHP serializados.
Tendrá características de rendimiento similares a los datos serializados.
Almacenamiento de base de datos
Esto se considera mejor cuando tiene una gran cantidad de configuración, pero es selectivo en lo que se necesita para la tarea actual. Me sorprendió descubrir que con alrededor de 150 elementos de datos, era más rápido recuperar los datos de una instancia de MySQL local que a unserialize un archivo de datos.
¡OTOH no es un buen lugar para almacenar las credenciales que usa para conectarse a su base de datos!
El entorno de ejecución.
Puede establecer valores en el entorno de ejecución en el que se ejecuta PHP.
Esto elimina cualquier requisito para que el código PHP busque en un lugar específico para la configuración. OTOH no se adapta bien a grandes cantidades de datos y es difícil de cambiar universalmente en tiempo de ejecución.
En el cliente
Un lugar que no he mencionado para almacenar datos de configuración está en el cliente. Nuevamente, la sobrecarga de la red significa que esto no se adapta bien a grandes cantidades de configuración. Y dado que el usuario final tiene el control sobre los datos, debe almacenarse en un formato donde se pueda detectar cualquier manipulación (es decir, con una firma criptográfica) y no debe contener ninguna información que se vea comprometida por su divulgación (es decir, cifrada de manera reversible).
A la inversa, esto tiene muchos beneficios para almacenar información confidencial que es propiedad del usuario final: si no la almacena en el servidor, no puede ser robada desde allí.
Directorios de red Otro lugar interesante para almacenar información de configuración es en DNS / LDAP. Esto funcionará para una pequeña cantidad de pequeñas piezas de información, pero no es necesario atenerse a la primera forma normal, considere, por ejemplo, SPF .
La infraestructura admite el almacenamiento en caché, la replicación y la distribución. Por lo tanto, funciona bien para infraestructuras muy grandes.
Sistemas de control de versiones
La configuración, al igual que el código, debe administrarse y controlarse la versión, por lo tanto, obtener la configuración directamente de su sistema de VC es una solución viable. Pero a menudo esto conlleva una sobrecarga de rendimiento significativa, por lo que el almacenamiento en caché puede ser recomendable.
Normalmente termino creando un solo archivo conn.php que tiene mis conexiones de base de datos. Luego incluyo ese archivo en todos los archivos que requieren consultas de base de datos.
Puedes crear una clase de configuración con propiedades estáticas.
class Config
{
static $dbHost = ''localhost'';
static $dbUsername = ''user'';
static $dbPassword = ''pass'';
}
entonces puedes simplemente usarlo:
Config::$dbHost
A veces, en mis proyectos, uso un patrón de diseño SINGLETON para acceder a los datos de configuración. Es muy cómodo de usar.
¿Por qué?
Por ejemplo tienes 2 fuentes de datos en tu proyecto. Y usted puede elegir la bruja de ellos está habilitada.
- mysql
- json
En algún lugar del archivo de configuración que elija:
$dataSource = ''mysql'' // or ''json''
Cuando cambia la fuente completa, la aplicación debe cambiar al nuevo origen de datos, funciona bien y no necesita cambios en el código.
Ejemplo:
Config:
class Config
{
// ....
static $dataSource = ''mysql'';
/ .....
}
Clase de singleton:
class AppConfig
{
private static $instance;
private $dataSource;
private function __construct()
{
$this->init();
}
private function init()
{
switch (Config::$dataSource)
{
case ''mysql'':
$this->dataSource = new StorageMysql();
break;
case ''json'':
$this->dataSource = new StorageJson();
break;
default:
$this->dataSource = new StorageMysql();
}
}
public static function getInstance()
{
if (empty(self::$instance)) {
self::$instance = new self();
}
return self::$instance;
}
public function getDataSource()
{
return $this->dataSource;
}
}
... y en algún lugar de su código (por ejemplo, en alguna clase de servicio):
$container->getItemsLoader(AppConfig::getInstance()->getDataSource()) // getItemsLoader need Object of specific data source class by dependency injection
Podemos obtener un objeto AppConfig desde cualquier lugar del sistema y siempre obtener la misma copia (gracias a static). El método init () de la clase se llama En el constructor, que garantiza una sola ejecución. El cuerpo de Init () comprueba el valor de config $ dataSource y crea un nuevo objeto de una clase de fuente de datos específica. Ahora nuestro script puede obtener objetos y operar con él, sin saber siquiera qué implementación específica existe realmente.
Si cree que va a utilizar más de 1 db por cualquier motivo, vaya con la variable porque podrá cambiar un parámetro para cambiar a un db completamente diferente. Es decir para pruebas, autobackup, etc.
Una forma simple pero elegante es crear un archivo config.php
(o como se llame) que solo devuelve una matriz:
<?php
return array(
''host'' => ''localhost'',
''username'' => ''root'',
);
Y entonces:
$configs = include(''config.php'');
Utilizo una ligera evolución de la solución de @hugo_leonardo:
<?php
return (object) array(
''host'' => ''localhost'',
''username'' => ''root'',
''pass'' => ''password'',
''database'' => ''db''
);
?>
Esto le permite usar la sintaxis del objeto cuando incluye php: $configs->host
lugar de $configs[''host'']
.
Además, si su aplicación tiene las configuraciones que necesita en el lado del cliente (como para una aplicación Angular), puede hacer que este archivo config.php
contenga todas sus configuraciones (centralizadas en un archivo en lugar de una para JavaScript y otra para PHP). El truco sería entonces tener otro archivo PHP que se hiciera echo
solo de la información del lado del cliente (para evitar mostrar información que no desea mostrar como una cadena de conexión de base de datos). Llámalo decir get_app_info.php
:
<?php
$configs = include(''config.php'');
echo json_encode($configs->app_info);
?>
Lo anterior suponiendo que su config.php
contiene un parámetro app_info
:
<?php
return (object) array(
''host'' => ''localhost'',
''username'' => ''root'',
''pass'' => ''password'',
''database'' => ''db'',
''app_info'' => array(
''appName''=>"App Name",
''appURL''=> "http://yourURL/#/"
)
);
?>
Por lo tanto, la información de su base de datos permanece en el lado del servidor, pero se puede acceder a la información de su aplicación desde su JavaScript, por ejemplo, con $http.get(''get_app_info.php'').then(...);
tipo de llamada.