Insertar NOW () en la base de datos con el registro activo de CodeIgniter

78

Quiero insertar la hora actual en la base de datos usando la función mySQL NOW () en el registro activo de Codeigniter. La siguiente consulta no funcionará:

$data = array(
        'name' => $name ,
        'email' => $email,
        'time' => NOW()
        );
        $this->db->insert('mytable', $data);

Esto se debe a que la clase ActiveRecord de CodeIgniter escapa automáticamente de la entrada.

Lo siguiente funciona bien, llamando a set () y pasando el parámetro FALSE, para que no escape NOW ().

$data = array(
        'name' => $name ,
        'email' => $email,
        );
        $this->db->set('time', 'NOW()', FALSE);
        $this->db->insert('mytable', $data);

Sin embargo, mi pregunta es: ¿hay alguna otra forma que no sea esta? Por ejemplo, ¿puedo usarlo de alguna manera agregando todo en la matriz de datos solamente? Por ejemplo, algo como:

$data = array(
            'name' => $name ,
            'email' => $email,
            'time' => NOW(), FALSE
            );
romano
fuente
1
Fuera de la pista e incluso alcance, pero ¿sabe que puede obtener un efecto similar al de NOW () usando strtotime? Por ejemplo, echo date("N", strtotime('now'));le dará la fecha de hoy, consulte php.net/strtotime y php.net/date
Kumar

Respuestas:

32

A menos que esté muy equivocado, la respuesta es: "No, no hay manera".

El problema básico en situaciones como esa es el hecho de que está llamando a una función MySQL y en realidad no está estableciendo un valor. CI escapa valores para que pueda hacer una inserción limpio, pero no prueba para ver si esos valores pasan a estar llamando a funciones como aes_encrypt, md5, o (en este caso) now(). Si bien en la mayoría de las situaciones esto es maravilloso, para esas situaciones, el único recurso es sql sin formato.

Por un lado, date('Y-m-d');debería funcionar como una versión de PHP NOW()para MySQL. (Sin embargo, no funcionará para todas las versiones de SQL).

Cwallenpoole
fuente
22
Para simplificar, siempre establezco marcas de tiempo con fecha ('Ymd H: i: s') con diferentes ORM, etc., sin necesidad de luchar contra diferentes implementaciones.
geekuality
2
Personalmente, siempre uso marcas de tiempo de Unix. Sé que 1308124173975 siempre será largo (o int, o flotante o equivalente) en todos los idiomas y bases de datos. Me gusta no tener que preocuparme.
cwallenpoole
1
Ese es un buen punto. Soy vago, así que me gusta tener entradas legibles por humanos si es posible. :)
geekuality
1
@jupaju Es solo un tipo diferente de pereza. Podría recordar cómo PgSQL, MySQL, Oracle, Java, PHP y Python almacenan las fechas, o podría hacer que todo fuera un número maldito. ¿Y sabes qué? Si es un número, se traduce instantáneamente en AS2, AS3 y JS. ¿Y cuando necesito la fecha real? Vaya a Chrome, Ctrl-shift-J y pegue la cadena (nueva fecha (/ * marca de tiempo numérica * /))
cwallenpoole
4
Me gustaría señalar que el uso de date ('Ymd H: i: s') puede tener un problema en el que el servidor MySQL y la biblioteca PHP están usando dos zonas horarias diferentes sin que usted lo sepa. Por ejemplo, tenía un host que tenía MySQL en GMT (+ 0h) y PHP era EST (-5h).
bafromca
76

Normalmente utilizo desencadenadores para manejar las marcas de tiempo, pero creo que esto puede funcionar.

$data = array(
    'name' => $name,
    'email' => $email
);

$this->db->set('time', 'NOW()', FALSE);
$this->db->insert('mytable', $data);
Bill H
fuente
alguna forma de usar de now() + 1 dayalguna manera para registros activos?
aspirinemaga
¿Hay alguna forma de que esto pueda activarse en una actualización vacía?
Edeph
1
Trabajó para mí también, CI2.1.2 en el año 2015
fedmich
1
@AnwarHossain Estoy usando la versión 3.1 y está funcionando, podría haber algún otro problema.
Muhammad
1
Estoy usando CI versión 3.1.8 y funciona absolutamente bien :)
haidarvm
14

aspirinemaga, simplemente reemplace:

$this->db->set('time', 'NOW()', FALSE);
$this->db->insert('mytable', $data);

para ello:

$this->db->set('time', 'NOW() + INTERVAL 1 DAY', FALSE);
$this->db->insert('mytable', $data);
Bruno Rigolon
fuente
2
Me gustaría señalar que, según los documentos, esta es la "forma recomendada" de CodeIgniter. Recomendaría usar el NOW () nativo de MySQL en lugar de la fecha de PHP ('Ymd H: i: s') si está en un host compartido, ya que pueden estar configurados en diferentes zonas horarias.
bafromca
11

Esta es la forma fácil de manejar la inserción de la marca de tiempo.

$data = array('created_on' => date('Y-m-d H:i:s'));
saurabh kamble
fuente
8
    $data = array(
            'name' => $name ,
            'email' => $email,
            'time' =>date('Y-m-d H:i:s')
            );
            $this->db->insert('mytable', $data);
sandeep kumar
fuente
Esta respuesta se ha marcado como de baja calidad. Si responde la pregunta, considere agregar un poco de texto para explicar cómo funciona.
lmo
3
Trabajó para mi. La explicación podría ayudar, pero resolvió mi problema. 😁
Jordan
time () no es necesario, date () siempre devuelve la hora actual
Loki
7

puede cargar el asistente de fecha y usar el interal codeigniter now () si desea hacer referencia al desplazamiento de tiempo GMT de los usuarios

se vería algo así

$data = array(
'created_on' => date('Y-m-d H:i:s',now())
);

Si no usa la configuración maestra de GTM y deja que sus usuarios establezcan sus propias compensaciones, no hay ninguna ventaja sobre el uso de la función time () de php.

Steven
fuente
date () advierte a php que no debe confiar en los sistemas date
pankijs
4

Según el código fuente de codeigniter, la función setse define como:

public function set($key, $value = '', $escape = TRUE)
{
    $key = $this->_object_to_array($key);

    if ( ! is_array($key))
    {
        $key = array($key => $value);
    }

    foreach ($key as $k => $v)
    {
        if ($escape === FALSE)
        {
            $this->ar_set[$this->_protect_identifiers($k)] = $v;
        }
        else
        {
            $this->ar_set[$this->_protect_identifiers($k, FALSE, TRUE)] = $this->escape($v);
        }
    }

    return $this;
}

Aparentemente, si $keyes una matriz, codeigniter simplemente ignorará el segundo parámetro $value, pero el tercer parámetro $escapeseguirá funcionando durante la iteración de $key, por lo que en esta situación, los siguientes códigos funcionan (usando el método de cadena):

$this->db->set(array(
    'name' => $name ,
    'email' => $email,
    'time' => 'NOW()'), '', FALSE)->insert('mytable');

Sin embargo, esto eliminará todos los datos, por lo que puede dividirlos en dos partes:

$this->db->set(array(
    'name' => $name ,
    'email' => $email))->set(array('time' => 'NOW()'), '', FALSE)->insert('mytable');
Junliang Huang
fuente
3

poner NOW () entre comillas no funcionará ya que Active Records pondrá el escape NOW () en una cadena e intentará insertarlo en la base de datos como una cadena de "NOW ()" ... necesitará usar

$this->db->set('time', 'NOW()', FALSE); 

para configurarlo correctamente.

siempre puede verificar su sql después con

$this->db->last_query();
williamli
fuente
3

Usar el asistente de fecha funcionó para mí

$this->load->helper('date');

Puede encontrar documentación date_helper aquí .

$data = array(
  'created' => now(),
  'modified' => now()
);

$this->db->insert('TABLENAME', $data);
Brandon Hollenbeck
fuente
Creo que es un enlace muerto
Anwar Hossain
0

$this->db->query("update table_name set ts = now() where 1=1") ¡también funciona para la marca de tiempo actual!

Kiran P.
fuente
0

ejecutar la consulta para obtener ahora () desde mysql, es decir, seleccionar ahora () como ahora enmysql;

luego use codeigniter para obtener esto y poner

$data['created_on'] = $row->noinmyssql;
$this->db->insert($data);
khalrd
fuente