Error 500 con Nginx+Chroot+PHP5-FPM+PhpMyadmin

Despues de hacer la instalación de Nginx y PHP5-FPM con Chroot (Jail) e instalar MySQL PhpMyAdmin la página me daba un error 500.

Investigando veo que el problema esta en la siguiente línea del archivo library/common.inc.php de PhpMyAdmin.

date_default_timezone_set(@date_default_timezone_get());

El problema está en que la función date_default_timezone_get() y todo se debe a que no se tienen los archivos necesarios para buscar la timezone del servidor, como lo muestra el log de nginx

[error] 12058#0: *13 FastCGI sent in stderr: “PHP message: PHP Fatal error: date_default_timezone_get(): Timezone database is corrupt – this should *never* happen! in /var/www/phpmyadmin/libraries/common.inc.php on line 276” while reading response header from upstream, client: 111.111.111.111, server: miservidor.com, request: “GET /phpmyadmin/ HTTP/1.1”, upstream: “fastcgi://127.0.0.1:9000”, host: “miservidor.com”

La solución es instalar la timezonedb con PHP-PEAR ( pecl ), procedemos con el siguiente código:

apt-get install php-pear php5-dev
pecl install timezonedb
echo ‘extension=timezonedb.so’> /etc/php5/mods-available/timezonedb.ini
ln -sf /etc/php5/mods-available/timezonedb.ini /etc/php5/fpm/conf.d/30-timezonedb.ini
service php5-fpm restart

Y listo!!.. ya debe de funcionar correctamente la página de PhpMyAdmin

MySQL: Como sumar un campo tipo Time

Si tienen un campo tipo Time (formato: 00:00:00) en su base de datos MySQL, y quieren hacer una suma con la tipica consulta:

SELECT SUM(campo_hora) FROM tabla

Verán que no regresa el resultado deseado…, eso es por el tipo de dato, entonces lo que se tiene que hacer es convertir a tipo numérico (segundos), sumar y después volver a convertir a tipo time., todo tan simple como usar una instrucción como sigue:

SELECT SEC_TO_TIME( SUM( TIME_TO_SEC( campo_hora ) ) ) FROM tabla

Y listo!!.., asunto arreglado.

MySQL y Visual Basic: El proveedor de datos u otro servicio devolvió un estado E_FAIL

Estaba revisando un sistema creado en visual basic 6 y a veces me marcaba el siguiente error:

El proveedor de datos u otro servicio devolvió un estado E_FAIL.

Viendo la consulta SQL me doy cuenta que la constante es que siempre había por lo menos 1 fecha con formato 0000-00-00 o mejor dicho NULL.

Y revisando la estructura de las tablas, el campo estaba definidio como datetime o date pero decía NOT NULL, la solución es poner los campos fecha a NULL, así ya no arrojara el ODBC el error de E_FAIL.

PHP: Convertir fecha de Twitter del formato RFC 2822 a uno de MySQL

Pues he estado probando la API de twitter y el campo created_at tiene la fecha en formato RFC 2822, osea en español algo así: Sun, 14 Aug 2005 16:13:03 +0000, el problema esta al guardar la información en la base de datos MySQL, ya que solo acepta formato “YYYY-MM-DD HH:MM:SS” entonces, ocupamos modificar esta información.

la solución esta en utilizar 2 funciones de PHP: strtotime y date

strtotime lo que hace es convertir una descripción de fecha/hora textual en Inglés a una fecha Unix y con comando date le damos el formato que deseemos.

Teniendo algo así.

date(‘Y-m-d H:i:s’,strtotime($json->created_at))

Codeigniter: Modificar LIMIT para el driver MSSQL

Después de encontrar la solución para que funcione el LIMIT de MySQL en Microsoft SQL Server ahora sigue el turno de modificar el código de Codeigniter para así tener algo transparente para nuestras consultas SQL.

Lo primero que se debe de hacer es modificar la librería de carga del Codeigniter, ( $this->load-> )
Vamos a trabajar en la carpeta: /system/application/libraries/ y creamos un archivo llamado: MY_Loader.php con el siguiente código:

< ?php class MY_Loader extends CI_Loader{ / * Constructor, calls parent constructor. */ function MY_Loader() { parent::CI_Loader(); } / * Database Loader * * @access public * @param string the DB credentials * @param bool whether to return the DB object * @param bool whether to enable active record (this allows us to override the config setting) * @return object */ function database($params = '', $return = FALSE, $active_record = FALSE) { // Do we even need to load the database class? if (class_exists('CI_DB') AND $return == FALSE AND $active_record == FALSE) { return FALSE; } require_once(BASEPATH.'database/DB'.EXT); // Load the DB class $db =& DB($params, $active_record); $my_driver = config_item('subclass_prefix').'DB_'.$db->dbdriver.’_driver’;
$my_driver_file = APPPATH.’libraries/’.$my_driver.EXT;

if (file_exists($my_driver_file))
{
require_once($my_driver_file);
$db =& new $my_driver(get_object_vars($db));
}

if ($return === TRUE)
{
return $db;
}
// Grab the super object
$CI =& get_instance();

// Initialize the db variable. Needed to prevent
// reference errors with some configurations
$CI->db = ”;
$CI->db = $db;
// Assign the DB object to any existing models
$this->_ci_assign_to_models();
}

}

La idea de este archivo es extender la funcionalidad de carga de los drivers para la base de datos, despues en la misma carpeta de libraries creamos un archivo llamado: MY_DB_mssql_driver.php ya que estamos usando el driver mssql para nuestra conexión SQL Server

< ?php class MY_DB_mssql_driver extends CI_DB_mssql_driver { function __construct($params){ parent::__construct($params); log_message('debug', 'Extended DB driver class instantiated!'); } function _limit($sql, $limit, $offset){ if($offset == 0){ return preg_replace('/(^\SELECT (DISTINCT)?)/i','\\1 TOP '.$limit.' ', $sql); }else{ $OrderBy = "ORDER BY "; if (count($this->ar_orderby) > 0){
$OrderBy .= implode(‘, ‘, $this->ar_orderby);

if ($this->ar_order !== FALSE)
{
$OrderBy .= ($this->ar_order == ‘desc’) ? ‘ DESC’ : ‘ ASC’;
}
}else{
$OrderBy .= “(SELECT 1)”;
}

$sql = preg_replace(‘/(\\’. $OrderBy .’\n?)/i’,”, $sql);
$sql = preg_replace(‘/(^\SELECT (DISTINCT)?)/i’,’\\1 ROW_NUMBER() OVER (‘.$OrderBy.’) AS rownum, ‘, $sql);
return “SELECT * \nFROM (\n” . $sql . “) AS A \nWHERE A.rownum BETWEEN (” .($offset + 1) . “) AND (“.($offset + $limit).”)”;
}
}

Y listo! con esto nuestra consulta LIMIT será transparente y se usará como siempre: $this->db->limit(2,10);

Aca les dejo las fuentes de esta información:

MySQL: Cannot add or update a child row: a foreign key constraint fails

Si al hacer un insert les marca el siguiente error en MySQL:

Cannot add or update a child row: a foreign key constraint fails

La solución es cambiar el motor de almacenamiento MyISAM a InnoDB de la tabla que tiene la referencia, una vez realizado este cambio ya debe de funcionar el insert (claro, siempre y cuando exista el valor del ID que hace referencia).

Aca pueden ver más información sobre las relaciones de tablas en MySQL

Resetear la contraseña del usuario Root en MySql

Si por alguna razón se les olvido la contraseña del usuario ROOT en MySQL existe una opción sencilla para cambiarla, el unico requisito es claro tener privilegios de root en su distribución de linux favorita, ya sea ubuntu, debian, centos, etc… en estos ejemplos usaremos Ubuntu (ó Debian debe de jalar igual)

El paso 1 es detener el servidor MySQL,

/etc/init.d/mysql stop

Despues iniciar MySQL saltando la autentificación y deshabilitando la escucha de la red, digo por aquello de los hackers, con el siguiente comando tambien habilitamos el servicio en background (con el amperson se indica eso)

mysqld –skip-grant-tables –skip-networking &

Ahora si, nos conectamos al servidor de MySQL, especificamente la tabla mysql

mysql mysql -u root

Y pues a ejecutar el siguiente comando:

UPDATE user SET password=PASSWORD(‘mi_nueva_clave’) WHERE user=”root”;
quit;

Y listo!, matamos el proceso y reiniciamos mysql normalmente., para ver el proceso cuando lo lanzamos en background nos aparecio un número del proceso.

kill -9 NUMERO

Y listo!, a iniciar el servicio (quizas con el restart mata el proceso, pero mejor el kill para estar seguros):

/etc/init.d/mysql restart

A disfrutar del MySQL y claro! no olvidar la clave! jeje.