2010-06-24 10 views
12

En algún momento implementaré cambios localmente y funcionan bien, los copio en mi servidor web remoto y los cambios son ignorados. (El código es idéntico.)cakephp: ¿por qué algunos cambios NO suceden hasta que cambie la depuración a 3?

Voy a core.php, cambio la depuración a 3, vuelva a verificar ... ¡funciona!

Tengo la sensación de que tiene algo que ver con la memoria caché, pero no sé exactamente qué cambiar.

+0

Similar: http://stackoverflow.com/questions/14716004/cakephp-database-table-missing-datasource-default – trante

Respuesta

25

CakePHP tiene un caché ubicado en /app/tmp/cache. La estructura del directorio tiene este aspecto:

# /app/tmp/cache 
# /app/tmp/cache/models 
# /app/tmp/cache/persistent 
# /app/tmp/cache/views 

El problema principal que generalmente se experimenta es con la memoria caché del modelo. Cuando la depuración está desactivada (es decir, en producción) y hace que CakePHP envíe, introspecta el esquema de todas las tablas de su base de datos y las almacena en archivos planos en la carpeta models arriba. Si no elimina los archivos en esta carpeta, CakePHP comenzará a decir que los modelos/tablas/campos no existen cuando claramente lo hacen en su base de datos.

Si habilita el almacenamiento en caché de la vista en su aplicación, cuando se visualizan las vistas por primera vez, CakePHP compilará archivos sin formato en la carpeta views para evitar tener que volver a representarlas en la próxima solicitud.

Durante el proceso de arranque de CakePHP, debe determinar la estructura de directorios que está utilizando en su instalación antes de que pueda acceder a archivos importantes (como database.php). Como tal, CakePHP generará archivos de caché en el directorio persistent con las rutas absolutas a todos y cada uno de los directorios y archivos importantes, cualquier complemento que esté utilizando e incluso cualquier localización que haya creado para que pueda traducir rápidamente su aplicación entre idiomas sin repaing .pot archivos .

En pocas palabras, debe recordar eliminar todos los archivos en estos directorios cada vez que realice cambios de código en una aplicación en producción, o agréguela como parte de su deployment mechanism. Usted no debe borrar cualquiera de los directorios sin embargo. El motivo por el que se cambia la depuración a 3 funciona es que cuando se activa el modo de depuración (en cualquier valor mayor a cero) la memoria caché se borra y se regenera en cada solicitud, pero, mientras esto funciona, no es fácil de automatizar. .

Hay varias maneras de hacerlo mediante programación, incluidos shell commands, CakePHP plugins, Capistrano configs, archivos Ant, pero también se puede hacer manualmente.

+0

Muy buena respuesta, muchas gracias. – Owen

+1

Sí, estableciendo 'Configure :: write ('Cache.disable', true);' es útil para no tener caché. –

1

Creo que es un problema del lado del cliente. ¿Tiene el Web Developer addon para Firefox Mozilla instalado? En caso afirmativo, puede desactivar fácilmente la memoria caché en el lado del cliente solo para verificar.

Funciona de nuevo si cambia el nivel de depuración porque entonces los datos de las urls y de las cookies son probablemente ligeramente diferentes, lo que lleva a una nueva recarga del servidor. Si todavía no funciona, debe ser la caché del lado del servidor ...

NOTA: Además de esto, puede hacer todo tipo de cosas útiles para el desarrollo web con ese complemento como modificar CSS sobre la marcha o visualizar estilos como superposición en la pagina.

+0

Gracias por la sugerencia de complemento Web Developer. Pensé que había desactivado el caché al poner Cache :: config ('default', array ('engine' => 'File', 'duration' => 0)); en core.php - ¿Supongo que estoy haciendo eso mal? – Owen

2

Definitivamente es el almacenamiento en caché. En el lado del servidor, si tiene habilitado el almacenamiento en caché, no se pregunte si ocurre el almacenamiento en caché. Puede desactivar esto en core.php, o más probablemente borre el caché Cache::clear() cuando actualice su aplicación. En el lado del cliente, es posible que desee ajustar su navegador para desactivar completamente el almacenamiento en caché.

+0

... ¿Cache :: clear() está mejor ubicado en el controlador? – Owen

+0

donde quiera. Podría tener una acción de controlador especial y restringido que borre todo el caché del lado del servidor. Solo tiene que visitar su URL después de una actualización. – sibidiba

+0

Afinar el navegador no afectará la caché del lado del servidor, ¿no? – Leo

1

Tuve el mismo problema, y ​​deizel, dio una excelente explicación, solo quería agregar, si no hace muchos cambios, de la manera más sencilla, sin eliminar o borrar los datos de la caché, o algo así, es cambiar el nivel de depuración de 0 a 3, actualizar la (s) página (s), hacer cambios en el archivo po, y volver a configurar la depuración a 0.

6

Puede encontrar esto útil para borrar la memoria caché en CakePHP 1.2, 1.3 y Creo que esto funcionaría en 2.x (con una pequeña modificación para hacer uso de la nueva clase CakeRequest):

if(Configure::read('debug') > 0 and isset($this->params['url']['emptycache'])) { 
     // clear Cache::write() items 
     Cache::clear(); 
     // clear core cache 
     $cachePaths = array('views', 'persistent', 'models'); 
     foreach($cachePaths as $config) { 
      clearCache(null, $config); 
     } 
     $this->Session->setFlash('Cache cleared', 'default', array(), 'info'); 
    } 

Añadir esto en su AppController :: beforeFilter().

Básicamente mientras se encuentra en modo de desarrollo, el código anterior le permite borrar fácilmente su caché al agregar una cadena de consulta a la URL, p. mydomain.com/?emptycache - eliminará todos los archivos en caché de Cake.

+0

Hmm, me encuentro con un problema donde modifico una tabla y luego muevo los datos en una sola llamada (ejecutar desde shell) y 'clearCache (null, 'modelos');' no parece estar funcionando (Cake está eliminando la nueva columna antes de enviar la consulta a mysql). La solución probablemente será dividir esto en 2 llamadas desde el shell, de modo que en la segunda ejecución se actualice la caché. (Pastel 1.3) – JoshStrange

1

He encontrado una solución maravillosa here. Creo que debería ser perfecto y funciona bien. La solución, como a continuación:

function _clear_cache() 
    { 

     Cache::clear(); 
     clearCache(); 

     $files = array(); 
     $files = array_merge($files, glob(CACHE . '*')); // remove cached css 
     $files = array_merge($files, glob(CACHE . 'css' . DS . '*')); // remove cached css 
     $files = array_merge($files, glob(CACHE . 'js' . DS . '*')); // remove cached js 
     $files = array_merge($files, glob(CACHE . 'models' . DS . '*')); // remove cached models 
     $files = array_merge($files, glob(CACHE . 'persistent' . DS . '*')); // remove cached persistent 

     foreach ($files as $f) { 
      if (is_file($f)) { 
       try { 
        @unlink($f); 
       } catch (Exception $ex) { 
        $files['errors'][] = $ex->getMessage(); 
       } 
      } 
     } 

     if (function_exists('apc_clear_cache')): 
      apc_clear_cache(); 
      apc_clear_cache('user'); 
     endif; 

     return $files; 

    } 

sólo tiene que utilizar la función anterior en su AppController y ejecutar esa función en la que desea estará claro todo caché.

Cuestiones relacionadas