Archivo de la categoría ‘PHP’

Modificar el tiempo de vida de una sesión en php

Martes, 8 de Junio de 2010

Las sesiones en php tienen múltiples usos, el más habitual, el de mantener activo un usuario logueado. En la mayoría de configuraciones de php el SID se propaga mediante cookies, por lo que para modificar el tiempo de vida de una sesión debe usarse la directiva session.cookie_lifetime.

Por ejemplo, para setear sesiones de dos minutos:

ini_set(”session.cookie_lifetime”,120);  //El tiempo viene dado en segundos

Además, será necesario combinarlo con el valor gc_maxlifetime para que el recolector de basura de php no elimine la cookie antes de su expiración.

Siguiendo el ejemplo de los dos minutos, deberíamos inicar lo siguiente:

ini_set(”session.gc_maxlifetime”, 120);

Por último, recordar que estos parámetros deben cambiarse antes de la instrucción session_start(); que es la que nos seteará la cookie en el caso de que ésta no estuviera ya en servidor.

Importante: Es posible que intentéis modificar este tiempo y os de la sensación de que no funciona. Hay que tener en cuenta que es posible que hayáis modificado el código pero vuestro equipo siga teniendo una cookie activa, por lo que hasta que no caduque la anterior no se os guardará la nueva con el tiempo de vida actualizado. Lo mejor para hacer pruebas es disponer de una herramienta como web developer toolbar que os permitirá controlar las cookies, pudiendo eliminar la antigua y comprobar que el código funciona correctamente.

Problema strtoupper con acentos

Viernes, 4 de Diciembre de 2009

Si en PHP queremos pasar un String con acentos, diéresi o diferentes letras de codificación UTF-8 a mayúsculas, directamente no podemos utilizar

PHP:
  1. $var = strtoupper($valor);

ya que transformará a mayúsculas únicamente las letras del abecedario simple (sin contar ñ ni ç).

La forma correcta de cubrir todos los casos es:

PHP:
  1. $var =   mb_strtoupper($valor,'utf-8');

Aprender hacer expresiones regulares para quitar los tags de un texto en php

Jueves, 19 de Noviembre de 2009

Para eliminar los tags de un texto, ya sea en php o javascript o cualquier otro lenguaje, vamos a utiizar expresiones regulares.

la ideal para tags es:  .<[^>]+>.

Para aprender a como funcionan las expresiones regulares, podemos utilizar un simuladro muy bueno, que nos permite probar "in the fly", en tiempo real. Si la expressión regular es válida o hace lo que queremos.

Para ello te deja poner un texto donde reconocer y la expressión.

El sitio es:  regexpal.com

dedicado a luis.

allow memory en phpmyadmin al importar una BD

Martes, 27 de Octubre de 2009

Cuando importamos una base de datos grande y lo queremos hacer desde el PHPMYADMIN, puede ser que nos de un error de que no tiene memoria suficiente.

Para solucionarlo, si tenemos acceso al servidor. Podemos incrementar la memoria máxima de ejecución y el tiempo de ejecucución de los escripts php en generar desde el php.ini (el fichero de configuración de php)

Si el servidor está montado sobre un S.O. Linux, el ejemplo en concreto es sobre ubuntu

la ruta del fichero será /etc/php5/apache2/php.ini

Dentro del fichero buscar "Resource Limits":

;;;;;;;;;;;;;;;;;;;
; Resource Limits ;
;;;;;;;;;;;;;;;;;;;

max_execution_time = 60 ; Maximum execution time of each script, in seconds
max_input_time = 60 ; Maximum amount of time each script may spend parsing request data
;max_input_nesting_level = 64 ; Maximum input variable nesting level
;memory_limit = 16M      ; Maximum amount of memory a script may consume (16MB) ; Por defecto
memory_limit = 128M ; Maximum amount of memory a script may consume (16MB)

Ahí dentro, modificar las lineas en negrita (memory_limit y max_execution_time ) por los valores acordes a la importación que vaya hacer y la memoria disponible en el servidor.

despues reiniciar el apache para que surja efecto:

sudo /etc/init.d/apache2 restart

Una vez importada la bd es recomendabe volver a dejar el fichero como estaba.

Imprimir directo desde ms-dos. Tickets desde php bajo Windows

Jueves, 10 de Septiembre de 2009

Hace tiempo solventamos la impresión desde php a impresora de tickets bajo Linux mediante este método

Ahora tenemos la problemática de hacer lo mismo desde Windows. Existe la extensión printer pero nos interesa reutilizar la mayor parte del código, en este caso el cuerpo del ticket, para que las versiones bajo Windows y Linux difieran el mínimo posible.

Bien, siguiendo el mismo método necesitamos imprimir un fichero previamente generado desde php directamente desde consola (en este caso mediante comandos ms-dos). Ms-dos y las impresoras usb no se llevan bien, así que toca hacer un pequeño "apaño". Mapear el puerto LPT1 a un puerto de impresión de red con nuestra impresora previamente compartida en red. Estos son los pasos:

1) Nos asegurarnos de tener, al menos, una interfaz de red. En caso de no tener ninguna podemos añadir un adaptador ficticio, como "Adaptador de bucle invertido de Microsoft" y asignarle una IP.

2) Compartimos la impresora (que por cierto, debe ser sólo texto) en red. Recordamos el nombre que le asignamos como recurso compartido.

3) Mapeamos el puerto desde ms-dos con el siguiente comando: NET USE LPT1: \\[nombre_en_red_de_la_maquina]\[nombre_impresora] /PERSISTENT:YES

4) Ahora desde php ya podemos imprimir el fichero que queramos con: shell_exec('type nombre_fichero>lpt1');

Con un pequeño if que detecte el sistema operativo en que está instalado php podemos tener un sistema de impresión de tickets multiplataforma. Eso si, con nuestra intervención para mapear el puerto.

Dar permisos de administrador en phpbb 3

Lunes, 11 de Mayo de 2009

La "nueva" versión del popular foro trae una revisión profunda del panel de aministración. Me he encontrado con una instalación sin permisos por defecto. Aquí un recordatorio para poder acceder a foros y administrarlos:

  • Después de crear un nuevo foro, se deben asignar permisos: ACP/Foros/Permisos de foros. En esta pantalla, lo más cómodo es añadir permisos de grupos
  • Dar permisos de moderador a un usuario: ACP/Usuarios y grupos/Administrar grupos. Clicar sobre "usuarios" en el grupo de Moderadores globales y añadir usuarios.

Usado en amicsdelsclassics.com.

Enviar cookies o variables post desde file_get_contents() php

Miércoles, 25 de Febrero de 2009

Queremos hacer una petición de una página web externa, a la que necesitamos pasarle unos parámetros post y además una cookie con información adicional como el id de session.

la forma facil es mediante la función de php:

PHP:
  1. file_get_contents('http://webexterna.com/fichero.php',false,$contexto);

En el último parámetro que es el contexto, se le puede enviar información adicional. como el tipo de peticion http ( GET o POST), el protocolo (http o https), variables post, un parámetro de cookies.

el ejemplo completo sería:

PHP:
  1. $opciones = array('http' =>
  2.     array(
  3.         'method'  => 'GET',
  4.         'header'  => 'Content-type: text/plain;charset=UTF-8\r\n'.
  5.         'Referer: http://www.webanterior\r\n'.
  6.         'User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.1; es-ES; rv:1.9.0.6) Gecko/2009011913 Firefox/3.0.6\r\n'.
  7.         'Cookie: variableCookie1=valorCookie1; variablecookie2=valor2; variablecookie3=valor3; SESSIONID=TkddJlDQnk7vKKj7KvcKptGRJKgrhv4yKHZNTVdttdfqWKtG1LdT!;\r\n'
  8.     )
  9. );
  10.  
  11. $contexto  = stream_context_create($opciones); //crea el contexto para el stream
  12. $resultado = file_get_contents('http://www.webexterna.com/fichero.asp', false, $contexto);

Puedes ver mas opciones de como usar los contextos en php en: context php
ejemplo de la funcion stream_context_create en php

Otra manera sería usando una librería tipo curl, o una clase como Snoopy, una clase diseñada para enviar formularios post. Os la añado que cuesta de encontrar por google. tiene un nombre demasiado comun.

PHP:
  1. /*************************************************
  2. Snoopy - the PHP net client
  3. Author: Monte Ohrt <monte@ispi.net>
  4. Copyright (c): 1999-2000 ispi, all rights reserved
  5. Version: 1.01
  6. * This library is free software; you can redistribute it and/or
  7. * modify it under the terms of the GNU Lesser General Public
  8. * License as published by the Free Software Foundation; either
  9. * version 2.1 of the License, or (at your option) any later version.
  10. *
  11. * This library is distributed in the hope that it will be useful,
  12. * but WITHOUT ANY WARRANTY; without even the implied warranty of
  13. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  14. * Lesser General Public License for more details.
  15. *
  16. * You should have received a copy of the GNU Lesser General Public
  17. * License along with this library; if not, write to the Free Software
  18. * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  19. You may contact the author of Snoopy by e-mail at:
  20. monte@ispi.net
  21. Or, write to:
  22. Monte Ohrt
  23. CTO, ispi
  24. 237 S. 70th suite 220
  25. Lincoln, NE 68510
  26. The latest version of Snoopy can be obtained from:
  27. http://snoopy.sourceforge.net/
  28. *************************************************/
  29.  
  30. class Snoopy
  31. {
  32.     /**** Public variables ****/
  33.    
  34.     /* user definable vars */
  35.  
  36.     var $host         =  "www.dominio.com";        // host name we are connecting to
  37.     var $port         =  80;               // port we are connecting to
  38.     var $proxy_host  =    "";     // proxy host to use
  39.     var $proxy_port  =    "";     // proxy port to use
  40.     var $proxy_user  =    "";     // proxy user to use
  41.     var $proxy_pass  =    "";     // proxy password to use
  42.    
  43.     var $agent      = "Mozilla/5.0 (Windows; U; Windows NT 5.1; es-ES; rv:1.8.1.16) Gecko/20080702 Firefox/2.0.0.16"// agent we masquerade as
  44.     var $referer  =    "";     // referer info to pass
  45.     var $cookies        =   array();         // array of cookies to pass
  46.                                                 // $cookies["username"]="joe";
  47.     var $rawheaders    = array();   // array of raw headers to send
  48.                                                 // $rawheaders["Content-type"]="text/html";
  49.  
  50.     var $maxredirs    = 5;               // http redirection depth maximum. 0 = disallow
  51.     var $lastredirectaddr   =  "";            // contains address of last redirected address
  52.     var $offsiteok      =  true;    // allows redirection off-site
  53.     var $maxframes    = 0;               // frame content depth maximum. 0 = disallow
  54.     var $expandlinks    =   true;        // expand links to fully qualified URLs.
  55.                                                 // this only applies to fetchlinks()
  56.                                                 // submitlinks(), and submittext()
  57.     var $passcookies    =   true;        // pass set cookies back through redirects
  58.                                                 // NOTE: this currently does not respect
  59.                                                 // dates, domains or paths.
  60.    
  61.     var $user            =   "";                    // user for http authentication
  62.     var $pass            =   "";                    // password for http authentication
  63.    
  64.     // http accept types
  65.     var $accept   =    "image/gif, image/x-xbitmap, image/jpeg, image/pjpeg, */*";
  66.    
  67.     var $results        =   "";                    // where the content is put
  68.        
  69.     var $error      = "";          // error messages sent here
  70.     var $response_code   =  "";               // response code returned from server
  71.     var $headers  =    array();            // headers returned from server sent here
  72.     var $maxlength      =  500000;            // max return data length (body)
  73.     var $read_timeout   =  0;                    // timeout on read operations, in seconds
  74.                                                 // supported only since PHP 4 Beta 4
  75.                                                 // set to 0 to disallow timeouts
  76.     var $timed_out    = false;            // if a read operation timed out
  77.     var $status      = 0;               // http request status
  78.  
  79.     var $temp_dir      =  "/tmp";            // temporary directory that the webserver
  80.                                                 // has permission to write to.
  81.                                                 // under Windows, this should be C:\temp
  82.  
  83.     var $curl_path      =  "/usr/local/bin/curl";
  84.                                                 // Snoopy will use cURL for fetching
  85.                                                 // SSL content if a full system path to
  86.                                                 // the cURL binary is supplied here.
  87.                                                 // set to false if you do not have
  88.                                                 // cURL installed. See http://curl.haxx.se
  89.                                                 // for details on installing cURL.
  90.                                                 // Snoopy does *not* use the cURL
  91.                                                 // library functions built into php,
  92.                                                 // as these functions are not stable
  93.                                                 // as of this Snoopy release.
  94.    
  95.     /**** Private variables ****/   
  96.    
  97.     var $_maxlinelen =    4096;            // max line length (headers)
  98.    
  99.     var $_httpmethod    =   "GET";    // default http request method
  100.     var $_httpversion   =  "HTTP/1.0";         // default http request version
  101.     var $_submit_method =    "POST";    // default submit method
  102.     var $_submit_type   =  'multipart/form-data'; //"application/x-www-form-urlencoded"; // default submit type
  103.     var $_mime_boundary =   "application/octet-stream";          // MIME boundary for multipart/form-data submit type
  104.     var $_redirectaddr  = false;            // will be set if page fetched is a redirect
  105.     var $_redirectdepth =    0;          // increments on an http redirect
  106.     var $_frameurls  =    array();         // frame src urls
  107.     var $_framedepth    =   0;     // increments on frame depth
  108.    
  109.     var $_isproxy      =  false;                // set if using a proxy server
  110.     var $_fp_timeout    =   30;                    // timeout for socket connection
  111.  
  112. /*======================================================================*\
  113.     Function:   fetch
  114.     Purpose:    fetch the contents of a web page
  115.                 (and possibly other protocols in the
  116.                 future like ftp, nntp, gopher, etc.)
  117.     Input:    $URI  the location of the page to fetch
  118.     Output:  $this->results   the output text from the fetch
  119. \*======================================================================*/
  120.  
  121.     function fetch($URI)
  122.     {
  123.    
  124.         //preg_match("|^([^:]+)://([^:/]+)(:[\d]+)*(.*)|",$URI,$URI_PARTS);
  125.         $URI_PARTS = parse_url($URI);
  126.         if (!empty($URI_PARTS["user"]))
  127.             $this->user = $URI_PARTS["user"];
  128.         if (!empty($URI_PARTS["pass"]))
  129.             $this->pass = $URI_PARTS["pass"];
  130.         if (empty($URI_PARTS["query"]))
  131.             $URI_PARTS["query"] = '';
  132.         if (empty($URI_PARTS["path"]))
  133.             $URI_PARTS["path"] = '';
  134.                
  135.         switch(strtolower($URI_PARTS["scheme"]))
  136.         {
  137.             case "http":
  138.                 $this->host = $URI_PARTS["host"];
  139.                 if(!empty($URI_PARTS["port"]))
  140.                     $this->port = $URI_PARTS["port"];
  141.                 if($this->_connect($fp))
  142.                 {
  143.                     if($this->_isproxy)
  144.                     {
  145.                         // using proxy, send entire URI
  146.                         $this->_httprequest($URI,$fp,$URI,$this->_httpmethod);
  147.                     }
  148.                     else
  149.                     {
  150.                         $path = $URI_PARTS["path"].($URI_PARTS["query"] ? "?".$URI_PARTS["query"] : "");
  151.                         // no proxy, send only the path
  152.                         $this->_httprequest($path, $fp, $URI, $this->_httpmethod);
  153.                     }
  154.                    
  155.                     $this->_disconnect($fp);
  156.  
  157.                     if($this->_redirectaddr)
  158.                     {
  159.                         /* url was redirected, check if we've hit the max depth */
  160.                         if($this->maxredirs> $this->_redirectdepth)
  161.                         {
  162.                             // only follow redirect if it's on this site, or offsiteok is true
  163.                             if(preg_match("|^http://".preg_quote($this->host)."|i",$this->_redirectaddr) || $this->offsiteok)
  164.                             {
  165.                                 /* follow the redirect */
  166.                                 $this->_redirectdepth++;
  167.                                 $this->lastredirectaddr=$this->_redirectaddr;
  168.                                 $this->fetch($this->_redirectaddr);
  169.                             }
  170.                         }
  171.                     }
  172.  
  173.                     if($this->_framedepth <$this->maxframes && count($this->_frameurls)> 0)
  174.                     {
  175.                         $frameurls = $this->_frameurls;
  176.                         $this->_frameurls = array();
  177.                        
  178.                         while(list(,$frameurl) = each($frameurls))
  179.                         {
  180.                             if($this->_framedepth <$this->maxframes)
  181.                             {
  182.                                 $this->fetch($frameurl);
  183.                                 $this->_framedepth++;
  184.                             }
  185.                             else
  186.                                 break;
  187.                         }
  188.                     }               
  189.                 }
  190.                 else
  191.                 {
  192.                     return false;
  193.                 }
  194.                 return true;                   
  195.                 break;
  196.             case "https":
  197.                 if(!$this->curl_path)
  198.                     return false;
  199.                 if(function_exists("is_executable"))
  200.                     if (!is_executable($this->curl_path))
  201.                         return false;
  202.                 $this->host = $URI_PARTS["host"];
  203.                 if(!empty($URI_PARTS["port"]))
  204.                     $this->port = $URI_PARTS["port"];
  205.                 if($this->_isproxy)
  206.                 {
  207.                     // using proxy, send entire URI
  208.                     $this->_httpsrequest($URI,$URI,$this->_httpmethod);
  209.                 }
  210.                 else
  211.                 {
  212.                     $path = $URI_PARTS["path"].($URI_PARTS["query"] ? "?".$URI_PARTS["query"] : "");
  213.                     // no proxy, send only the path
  214.                     $this->_httpsrequest($path, $URI, $this->_httpmethod);
  215.                 }
  216.  
  217.                 if($this->_redirectaddr)
  218.                 {
  219.                     /* url was redirected, check if we've hit the max depth */
  220.                     if($this->maxredirs> $this->_redirectdepth)
  221.                     {
  222.                         // only follow redirect if it's on this site, or offsiteok is true
  223.                         if(preg_match("|^http://".preg_quote($this->host)."|i",$this->_redirectaddr) || $this->offsiteok)
  224.                         {
  225.                             /* follow the redirect */
  226.                             $this->_redirectdepth++;
  227.                             $this->lastredirectaddr=$this->_redirectaddr;
  228.                             $this->fetch($this->_redirectaddr);
  229.                         }
  230.                     }
  231.                 }
  232.  
  233.                 if($this->_framedepth <$this->maxframes && count($this->_frameurls)> 0)
  234.                 {
  235.                     $frameurls = $this->_frameurls;
  236.                     $this->_frameurls = array();
  237.  
  238.                     while(list(,$frameurl) = each($frameurls))
  239.                     {
  240.                         if($this->_framedepth <$this->maxframes)
  241.                         {
  242.                             $this->fetch($frameurl);
  243.                             $this->_framedepth++;
  244.                         }
  245.                         else
  246.                             break;
  247.                     }
  248.                 }               
  249.                 return true;                   
  250.                 break;
  251.             default:
  252.                 // not a valid protocol
  253.                 $this->error    =   'Invalid protocol "'.$URI_PARTS["scheme"].'"\n';
  254.                 return false;
  255.                 break;
  256.         }      
  257.         return true;
  258.     }
  259.  
  260. /*======================================================================*\
  261.     Function:   submit
  262.     Purpose:    submit an http form
  263.     Input:    $URI  the location to post the data
  264.                 $formvars   the formvars to use.
  265.                     format: $formvars["var"] = "val";
  266.                 $formfiles  an array of files to submit
  267.                     format: $formfiles["var"] = "/dir/filename.ext";
  268.     Output:  $this->results   the text output from the post
  269. \*======================================================================*/
  270.  
  271.     function submit($URI, $formvars="", $formfiles="")
  272.     {
  273.         unset($postdata);
  274. /*    Añadir cookies manualmente
  275.         $this->cookies["PHPSESSID"]='755a7835f6c772e36dc5c3d50d7c142c';
  276.         $this->cookies["autentificado"]='si';
  277.         $this->cookies["correo"]='tucorreo@gmail.com';
  278.         $this->cookies["id"]='2233';
  279.         $this->cookies["usuario"]='';
  280.     */ 
  281.        
  282.         $postdata = $this->_prepare_post_body($formvars, $formfiles);
  283.            
  284.         $URI_PARTS = parse_url($URI);
  285.         if (!empty($URI_PARTS["user"]))
  286.             $this->user = $URI_PARTS["user"];
  287.         if (!empty($URI_PARTS["pass"]))
  288.             $this->pass = $URI_PARTS["pass"];
  289.         if (empty($URI_PARTS["query"]))
  290.             $URI_PARTS["query"] = '';
  291.         if (empty($URI_PARTS["path"]))
  292.             $URI_PARTS["path"] = '';
  293.  
  294.         switch(strtolower($URI_PARTS["scheme"]))
  295.         {
  296.             case "http":
  297.                 $this->host = $URI_PARTS["host"];
  298.                 if(!empty($URI_PARTS["port"]))
  299.                     $this->port = $URI_PARTS["port"];
  300.                 if($this->_connect($fp))
  301.                 {
  302.                     if($this->_isproxy)
  303.                     {
  304.                         // using proxy, send entire URI
  305.                         $this->_httprequest($URI,$fp,$URI,$this->_submit_method,$this->_submit_type,$postdata);
  306.                     }
  307.                     else
  308.                     {
  309.                         $path = $URI_PARTS["path"].($URI_PARTS["query"] ? "?".$URI_PARTS["query"] : "");
  310.                         // no proxy, send only the path
  311.                         $this->_httprequest($path, $fp, $URI, $this->_submit_method, $this->_submit_type, $postdata);
  312.                     }
  313.                    
  314.                     $this->_disconnect($fp);
  315.  
  316.                     if($this->_redirectaddr)
  317.                     {
  318.                         /* url was redirected, check if we've hit the max depth */
  319.                         if($this->maxredirs> $this->_redirectdepth)
  320.                         {                  
  321.                             if(!preg_match("|^".$URI_PARTS["scheme"]."://|", $this->_redirectaddr))
  322.                                 $this->_redirectaddr = $this->_expandlinks($this->_redirectaddr,$URI_PARTS["scheme"]."://".$URI_PARTS["host"]);      
  323.                            
  324.                             // only follow redirect if it's on this site, or offsiteok is true
  325.                             if(preg_match("|^http://".preg_quote($this->host)."|i",$this->_redirectaddr) || $this->offsiteok)
  326.                             {
  327.                                 /* follow the redirect */
  328.                                 $this->_redirectdepth++;
  329.                                 $this->lastredirectaddr=$this->_redirectaddr;
  330.                                 if( strpos( $this->_redirectaddr, "?" )> 0 )
  331.                                     $this->fetch($this->_redirectaddr); // the redirect has changed the request method from post to get
  332.                                 else
  333.                                     $this->submit($this->_redirectaddr,$formvars, $formfiles);
  334.                             }
  335.                         }
  336.                     }
  337.  
  338.                     if($this->_framedepth <$this->maxframes && count($this->_frameurls)> 0)
  339.                     {
  340.                         $frameurls = $this->_frameurls;
  341.                         $this->_frameurls = array();
  342.                        
  343.                         while(list(,$frameurl) = each($frameurls))
  344.                         {                                          
  345.                             if($this->_framedepth <$this->maxframes)
  346.                             {
  347.                                 $this->fetch($frameurl);
  348.                                 $this->_framedepth++;
  349.                             }
  350.                             else
  351.                                 break;
  352.                         }
  353.                     }               
  354.                    
  355.                 }
  356.                 else
  357.                 {
  358.                     return false;
  359.                 }
  360.                 return true;                   
  361.                 break;
  362.             case "https":
  363.                 if(!$this->curl_path)
  364.                     return false;
  365.                 if(function_exists("is_executable"))
  366.                     if (!is_executable($this->curl_path))
  367.                         return false;
  368.                 $this->host = $URI_PARTS["host"];
  369.                 if(!empty($URI_PARTS["port"]))
  370.                     $this->port = $URI_PARTS["port"];
  371.                 if($this->_isproxy)
  372.                 {
  373.                     // using proxy, send entire URI
  374.                     $this->_httpsrequest($URI, $URI, $this->_submit_method, $this->_submit_type, $postdata);
  375.                 }
  376.                 else
  377.                 {
  378.                     $path = $URI_PARTS["path"].($URI_PARTS["query"] ? "?".$URI_PARTS["query"] : "");
  379.                     // no proxy, send only the path
  380.                     $this->_httpsrequest($path, $URI, $this->_submit_method, $this->_submit_type, $postdata);
  381.                 }
  382.  
  383.                 if($this->_redirectaddr)
  384.                 {
  385.                     /* url was redirected, check if we've hit the max depth */
  386.                     if($this->maxredirs> $this->_redirectdepth)
  387.                     {                  
  388.                         if(!preg_match("|^".$URI_PARTS["scheme"]."://|", $this->_redirectaddr))
  389.                             $this->_redirectaddr = $this->_expandlinks($this->_redirectaddr,$URI_PARTS["scheme"]."://".$URI_PARTS["host"]);      
  390.  
  391.                         // only follow redirect if it's on this site, or offsiteok is true
  392.                         if(preg_match("|^http://".preg_quote($this->host)."|i",$this->_redirectaddr) || $this->offsiteok)
  393.                         {
  394.                             /* follow the redirect */
  395.                             $this->_redirectdepth++;
  396.                             $this->lastredirectaddr=$this->_redirectaddr;
  397.                             if( strpos( $this->_redirectaddr, "?" )> 0 )
  398.                                 $this->fetch($this->_redirectaddr); // the redirect has changed the request method from post to get
  399.                             else
  400.                                 $this->submit($this->_redirectaddr,$formvars, $formfiles);
  401.                         }
  402.                     }
  403.                 }
  404.  
  405.                 if($this->_framedepth <$this->maxframes && count($this->_frameurls)> 0)
  406.                 {
  407.                     $frameurls = $this->_frameurls;
  408.                     $this->_frameurls = array();
  409.  
  410.                     while(list(,$frameurl) = each($frameurls))
  411.                     {                                          
  412.                         if($this->_framedepth <$this->maxframes)
  413.                         {
  414.                             $this->fetch($frameurl);
  415.                             $this->_framedepth++;
  416.                         }
  417.                         else
  418.                             break;
  419.                     }
  420.                 }               
  421.                 return true;                   
  422.                 break;
  423.                
  424.             default:
  425.                 // not a valid protocol
  426.                 $this->error    =   'Invalid protocol "'.$URI_PARTS["scheme"].'"\n';
  427.                 return false;
  428.                 break;
  429.         }      
  430.         return true;
  431.     }
  432.  
  433. /*======================================================================*\
  434.     Function:   fetchlinks
  435.     Purpose:    fetch the links from a web page
  436.     Input:    $URI  where you are fetching from
  437.     Output:  $this->results   an array of the URLs
  438. \*======================================================================*/
  439.  
  440.     function fetchlinks($URI)
  441.     {
  442.         if ($this->fetch($URI))
  443.         {         
  444.             if($this->lastredirectaddr)
  445.                 $URI = $this->lastredirectaddr;
  446.             if(is_array($this->results))
  447.             {
  448.                 for($x=0;$x<count($this->results);$x++)
  449.                     $this->results[$x] = $this->_striplinks($this->results[$x]);
  450.             }
  451.             else
  452.                 $this->results = $this->_striplinks($this->results);
  453.  
  454.             if($this->expandlinks)
  455.                 $this->results = $this->_expandlinks($this->results, $URI);
  456.             return true;
  457.         }
  458.         else
  459.             return false;
  460.     }
  461.  
  462. /*======================================================================*\
  463.     Function:   fetchform
  464.     Purpose:    fetch the form elements from a web page
  465.     Input:    $URI  where you are fetching from
  466.     Output:  $this->results   the resulting html form
  467. \*======================================================================*/
  468.  
  469.     function fetchform($URI)
  470.     {
  471.        
  472.         if ($this->fetch($URI))
  473.         {         
  474.  
  475.             if(is_array($this->results))
  476.             {
  477.                 for($x=0;$x<count($this->results);$x++)
  478.                     $this->results[$x] = $this->_stripform($this->results[$x]);
  479.             }
  480.             else
  481.                 $this->results = $this->_stripform($this->results);
  482.            
  483.             return true;
  484.         }
  485.         else
  486.             return false;
  487.     }
  488.    
  489.    
  490. /*======================================================================*\
  491.     Function:   fetchtext
  492.     Purpose:    fetch the text from a web page, stripping the links
  493.     Input:    $URI  where you are fetching from
  494.     Output:  $this->results   the text from the web page
  495. \*======================================================================*/
  496.  
  497.     function fetchtext($URI)
  498.     {
  499.         if($this->fetch($URI))
  500.         {         
  501.             if(is_array($this->results))
  502.             {
  503.                 for($x=0;$x<count($this->results);$x++)
  504.                     $this->results[$x] = $this->_striptext($this->results[$x]);
  505.             }
  506.             else
  507.                 $this->results = $this->_striptext($this->results);
  508.             return true;
  509.         }
  510.         else
  511.             return false;
  512.     }
  513.  
  514. /*======================================================================*\
  515.     Function:   submitlinks
  516.     Purpose:    grab links from a form submission
  517.     Input:    $URI  where you are submitting from
  518.     Output:  $this->results   an array of the links from the post
  519. \*======================================================================*/
  520.  
  521.     function submitlinks($URI, $formvars="", $formfiles="")
  522.     {
  523.         if($this->submit($URI,$formvars, $formfiles))
  524.         {         
  525.             if($this->lastredirectaddr)
  526.                 $URI = $this->lastredirectaddr;
  527.             if(is_array($this->results))
  528.             {
  529.                 for($x=0;$x<count($this->results);$x++)
  530.                 {
  531.                     $this->results[$x] = $this->_striplinks($this->results[$x]);
  532.                     if($this->expandlinks)
  533.                         $this->results[$x] = $this->_expandlinks($this->results[$x],$URI);
  534.                 }
  535.             }
  536.             else
  537.             {
  538.                 $this->results = $this->_striplinks($this->results);
  539.                 if($this->expandlinks)
  540.                     $this->results = $this->_expandlinks($this->results,$URI);
  541.             }
  542.             return true;
  543.         }
  544.         else
  545.             return false;
  546.     }
  547.  
  548. /*======================================================================*\
  549.     Function:   submittext
  550.     Purpose:    grab text from a form submission
  551.     Input:    $URI  where you are submitting from
  552.     Output:  $this->results   the text from the web page
  553. \*======================================================================*/
  554.  
  555.     function submittext($URI, $formvars = "", $formfiles = "")
  556.     {
  557.         if($this->submit($URI,$formvars, $formfiles))
  558.         {         
  559.             if($this->lastredirectaddr)
  560.                 $URI = $this->lastredirectaddr;
  561.             if(is_array($this->results))
  562.             {
  563.                 for($x=0;$x<count($this->results);$x++)
  564.                 {
  565.                     $this->results[$x] = $this->_striptext($this->results[$x]);
  566.                     if($this->expandlinks)
  567.                         $this->results[$x] = $this->_expandlinks($this->results[$x],$URI);
  568.                 }
  569.             }
  570.             else
  571.             {
  572.                 $this->results = $this->_striptext($this->results);
  573.                 if($this->expandlinks)
  574.                     $this->results = $this->_expandlinks($this->results,$URI);
  575.             }
  576.             return true;
  577.         }
  578.         else
  579.             return false;
  580.     }
  581.  
  582.    
  583.  
  584. /*======================================================================*\
  585.     Function:   set_submit_multipart
  586.     Purpose:    Set the form submission content type to
  587.                 multipart/form-data
  588. \*======================================================================*/
  589.     function set_submit_multipart()
  590.     {
  591.         $this->_submit_type = "multipart/form-data";
  592.     }
  593.  
  594.    
  595. /*======================================================================*\
  596.     Function:   set_submit_normal
  597.     Purpose:    Set the form submission content type to
  598.                 application/x-www-form-urlencoded
  599. \*======================================================================*/
  600.     function set_submit_normal()
  601.     {
  602.         $this->_submit_type = "application/x-www-form-urlencoded";
  603.     }
  604.  
  605.    
  606.    
  607.  
  608. /*======================================================================*\
  609.     Private functions
  610. \*======================================================================*/
  611.    
  612.    
  613. /*======================================================================*\
  614.     Function:   _striplinks
  615.     Purpose:    strip the hyperlinks from an html document
  616.     Input:    $document document to strip.
  617.     Output:  $match      an array of the links
  618. \*======================================================================*/
  619.  
  620.     function _striplinks($document)
  621.     {   
  622.         preg_match_all("'<\s*a\s.*?href\s*=\s*      # find <a href=
  623.                         ([\"\'])?               # find single or double quote
  624.                         (?(1) (.*?)\\1 | ([^\s\>]+))        # if quote found, match up to next matching
  625.                                                     # quote, otherwise match up to next space
  626.                         'isx",$document,$links);
  627.                        
  628.  
  629.         // catenate the non-empty matches from the conditional subpattern
  630.  
  631.         while(list($key,$val) = each($links[2]))
  632.         {
  633.             if(!empty($val))
  634.                 $match[] = $val;
  635.         }            
  636.        
  637.         while(list($key,$val) = each($links[3]))
  638.         {
  639.             if(!empty($val))
  640.                 $match[] = $val;
  641.         }      
  642.        
  643.         // return the links
  644.         return $match;
  645.     }
  646.  
  647. /*======================================================================*\
  648.     Function:   _stripform
  649.     Purpose:    strip the form elements from an html document
  650.     Input:    $document document to strip.
  651.     Output:  $match      an array of the links
  652. \*======================================================================*/
  653.  
  654.     function _stripform($document)
  655.     {   
  656.         preg_match_all("'<\/?(FORM|INPUT|SELECT|TEXTAREA|(OPTION))[^<>]*>(?(2)(.*(?=<\/?(option|select)[^<>]*>[\r\n]*)|(?=[\r\n]*))|(?=[\r\n]*))'Usi",$document,$elements);
  657.        
  658.         // catenate the matches
  659.         $match = implode("\r\n",$elements[0]);
  660.                
  661.         // return the links
  662.         return $match;
  663.     }
  664.  
  665.    
  666.    
  667. /*======================================================================*\
  668.     Function:   _striptext
  669.     Purpose:    strip the text from an html document
  670.     Input:    $document document to strip.
  671.     Output:  $text        the resulting text
  672. \*======================================================================*/
  673.  
  674.     function _striptext($document)
  675.     {
  676.        
  677.         // I didn't use preg eval (//e) since that is only available in PHP 4.0.
  678.         // so, list your entities one by one here. I included some of the
  679.         // more common ones.
  680.                                
  681.         $search = array("'<script[^>]*?>.*?</script>'si",   // strip out javascript
  682.                         "'<[\/\!]*?[^<>]*?>'si",            // strip out html tags
  683.                         "'([\r\n])[\s]+'",          // strip out white space
  684.                         "'&(quot|#34|#034|#x22);'i",        // replace html entities
  685.                         "'&(amp|#38|#038|#x26);'i",   // added hexadecimal values
  686.                         "'&(lt|#60|#060|#x3c);'i",
  687.                         "'&(gt|#62|#062|#x3e);'i",
  688.                         "'&(nbsp|#160|#xa0);'i",
  689.                         "'&(iexcl|#161);'i",
  690.                         "'&(cent|#162);'i",
  691.                         "'&(pound|#163);'i",
  692.                         "'&(copy|#169);'i",
  693.                         "'&(reg|#174);'i",
  694.                         "'&(deg|#176);'i",
  695.                         "'&(#39|#039|#x27);'",
  696.                         "'&(euro|#8364);'i",                // europe
  697.                         "'&a(uml|UML);'",               // german
  698.                         "'&o(uml|UML);'",
  699.                         "'&u(uml|UML);'",
  700.                         "'&A(uml|UML);'",
  701.                         "'&O(uml|UML);'",
  702.                         "'&U(uml|UML);'",
  703.                         "'&szlig;'i",
  704.                         );
  705.         $replace = array(   "",
  706.                             "",
  707.                             "\\1",
  708.                             "\"",
  709.                             "&",
  710.                             "<",
  711.                             ">",
  712.                             " ",
  713.                             chr(161),
  714.                             chr(162),
  715.                             chr(163),
  716.                             chr(169),
  717.                             chr(174),
  718.                             chr(176),
  719.                             chr(39),
  720.                             chr(128),
  721.                             "?",
  722.                             "?",
  723.                             "?",
  724.                             "?",
  725.                             "?",
  726.                             "?",
  727.                             "?",
  728.                         );
  729.                    
  730.         $text = preg_replace($search,$replace,$document);
  731.                                
  732.         return $text;
  733.     }
  734.  
  735. /*======================================================================*\
  736.     Function:   _expandlinks
  737.     Purpose:    expand each link into a fully qualified URL
  738.     Input:    $links            the links to qualify
  739.                 $URI            the full URI to get the base from
  740.     Output:  $expandedLinks   the expanded links
  741. \*======================================================================*/
  742.  
  743.     function _expandlinks($links,$URI)
  744.     {
  745.        
  746.         preg_match("/^[^\?]+/",$URI,$match);
  747.  
  748.         $match = preg_replace("|/[^\/\.]+\.[^\/\.]+$|","",$match[0]);
  749.         $match = preg_replace("|/$|","",$match);
  750.         $match_part = parse_url($match);
  751.         $match_root =
  752.         $match_part["scheme"]."://".$match_part["host"];
  753.                
  754.         $search = array(    "|^http://".preg_quote($this->host)."|i",
  755.                             "|^(\/)|i",
  756.                             "|^(?!http://)(?!mailto:)|i",
  757.                             "|/\./|",
  758.                             "|/[^\/]+/\.\./|"
  759.                         );
  760.                        
  761.         $replace = array(   "",
  762.                             $match_root."/",
  763.                             $match."/",
  764.                             "/",
  765.                             "/"
  766.                         );     
  767.                
  768.         $expandedLinks = preg_replace($search,$replace,$links);
  769.  
  770.         return $expandedLinks;
  771.     }
  772.  
  773. /*======================================================================*\
  774.     Function:   _httprequest
  775.     Purpose:    go get the http data from the server
  776.     Input:    $url    the url to fetch
  777.                 $fp   the current open file pointer
  778.                 $URI        the full URI
  779.                 $body      body contents to send if any (POST)
  780.     Output:  
  781. \*======================================================================*/
  782.    
  783.     function _httprequest($url,$fp,$URI,$http_method,$content_type="",$body="")
  784.     {
  785.         $cookie_headers = '';
  786.         if($this->passcookies && $this->_redirectaddr)
  787.             $this->setcookies();
  788.            
  789.         $URI_PARTS = parse_url($URI);
  790.         if(empty($url))
  791.             $url = "/";
  792.         $headers = $http_method." ".$url." ".$this->_httpversion."\r\n";       
  793.         if(!empty($this->agent))
  794.             $headers .= "User-Agent: ".$this->agent."\r\n";
  795.         if(!empty($this->host) && !isset($this->rawheaders['Host'])) {
  796.             $headers .= "Host: ".$this->host;
  797.             if(!empty($this->port))
  798.                 $headers .= ":".$this->port;
  799.             $headers .= "\r\n";
  800.         }
  801.         if(!empty($this->accept))
  802.             $headers .= "Accept: ".$this->accept."\r\n";
  803.         if(!empty($this->referer))
  804.             $headers .= "Referer: ".$this->referer."\r\n";
  805.         if(!empty($this->cookies))
  806.         {         
  807.             if(!is_array($this->cookies))
  808.                 $this->cookies = (array)$this->cookies;
  809.    
  810.             reset($this->cookies);
  811.             if ( count($this->cookies)> 0 ) {
  812.                 $cookie_headers .= 'Cookie: ';
  813.                 foreach ( $this->cookies as $cookieKey => $cookieVal ) {
  814.                 $cookie_headers .= $cookieKey."=".urlencode($cookieVal)."; ";
  815.                 }
  816.                 $headers .= substr($cookie_headers,0,-2) . "\r\n";
  817.             }
  818.         }
  819.         if(!empty($this->rawheaders))
  820.         {
  821.             if(!is_array($this->rawheaders))
  822.                 $this->rawheaders = (array)$this->rawheaders;
  823.             while(list($headerKey,$headerVal) = each($this->rawheaders))
  824.                 $headers .= $headerKey.": ".$headerVal."\r\n";
  825.         }
  826.         if(!empty($content_type)) {
  827.             $headers .= "Content-type: $content_type";
  828.             if ($content_type == "multipart/form-data")
  829.                 $headers .= "; boundary=".$this->_mime_boundary;
  830.             $headers .= "\r\n";
  831.         }
  832.         if(!empty($body))   
  833.             $headers .= "Content-length: ".strlen($body)."\r\n";
  834.         if(!empty($this->user) || !empty($this->pass)) 
  835.             $headers .= "Authorization: Basic ".base64_encode($this->user.":".$this->pass)."\r\n";
  836.        
  837.         //add proxy auth headers
  838.         if(!empty($this->proxy_user))   
  839.             $headers .= 'Proxy-Authorization: ' . 'Basic ' . base64_encode($this->proxy_user . ':' . $this->proxy_pass)."\r\n";
  840.  
  841.  
  842.         $headers .= "\r\n";
  843.        
  844.         // set the read timeout if needed
  845.         if ($this->read_timeout> 0)
  846.             socket_set_timeout($fp, $this->read_timeout);
  847.         $this->timed_out = false;
  848.        
  849.         fwrite($fp,$headers.$body,strlen($headers.$body));
  850.        
  851.         $this->_redirectaddr = false;
  852.         unset($this->headers);
  853.                        
  854.         while($currentHeader = fgets($fp,$this->_maxlinelen))
  855.         {
  856.             if ($this->read_timeout> 0 && $this->_check_timeout($fp))
  857.             {
  858.                 $this->status=-100;
  859.                 return false;
  860.             }
  861.                
  862.             if($currentHeader == "\r\n")
  863.                 break;
  864.                        
  865.             // if a header begins with Location: or URI:, set the redirect
  866.             if(preg_match("/^(Location:|URI:)/i",$currentHeader))
  867.             {
  868.                 // get URL portion of the redirect
  869.                 preg_match("/^(Location:|URI:)[ ]+(.*)/i",chop($currentHeader),$matches);
  870.                 // look for :// in the Location header to see if hostname is included
  871.                 if(!preg_match("|\:\/\/|",$matches[2]))
  872.                 {
  873.                     // no host in the path, so prepend
  874.                     $this->_redirectaddr = $URI_PARTS["scheme"]."://".$this->host.":".$this->port;
  875.                     // eliminate double slash
  876.                     if(!preg_match("|^/|",$matches[2]))
  877.                             $this->_redirectaddr .= "/".$matches[2];
  878.                     else
  879.                             $this->_redirectaddr .= $matches[2];
  880.                 }
  881.                 else
  882.                     $this->_redirectaddr = $matches[2];
  883.             }
  884.        
  885.             if(preg_match("|^HTTP/|",$currentHeader))
  886.             {
  887.                 if(preg_match("|^HTTP/[^\s]*\s(.*?)\s|",$currentHeader, $status))
  888.                 {
  889.                     $this->status= $status[1];
  890.                 }            
  891.                 $this->response_code = $currentHeader;
  892.             }
  893.                
  894.             $this->headers[] = $currentHeader;
  895.         }
  896.  
  897.         $results = '';
  898.         do {
  899.             $_data = fread($fp, $this->maxlength);
  900.             if (strlen($_data) == 0) {
  901.                 break;
  902.             }
  903.             $results .= $_data;
  904.         } while(true);
  905.  
  906.         if ($this->read_timeout> 0 && $this->_check_timeout($fp))
  907.         {
  908.             $this->status=-100;
  909.             return false;
  910.         }
  911.        
  912.         // check if there is a a redirect meta tag
  913.        
  914.         if(preg_match("'<meta[\s]*http-equiv[^>]*?content[\s]*=[\s]*[\"\']?\d+;[\s]*URL[\s]*=[\s]*([^\"\']*?)[\"\']?>'i",$results,$match))
  915.  
  916.         {
  917.             $this->_redirectaddr = $this->_expandlinks($match[1],$URI)
  918.         }
  919.  
  920.         // have we hit our frame depth and is there frame src to fetch?
  921.         if(($this->_framedepth <$this->maxframes) && preg_match_all("'<frame\s+.*src[\s]*=[\'\"]?([^\'\"\>]+)'i",$results,$match))
  922.         {
  923.             $this->results[] = $results;
  924.             for($x=0; $x<count($match[1]); $x++)
  925.                 $this->_frameurls[] = $this->_expandlinks($match[1][$x],$URI_PARTS["scheme"]."://".$this->host);
  926.         }
  927.         // have we already fetched framed content?
  928.         elseif(is_array($this->results))
  929.             $this->results[] = $results;
  930.         // no framed content
  931.         else
  932.             $this->results = $results;
  933.        
  934.         return true;
  935.     }
  936.  
  937. /*======================================================================*\
  938.     Function:   _httpsrequest
  939.     Purpose:    go get the https data from the server using curl
  940.     Input:    $url    the url to fetch
  941.                 $URI        the full URI
  942.                 $body      body contents to send if any (POST)
  943.     Output:  
  944. \*======================================================================*/
  945.    
  946.     function _httpsrequest($url,$URI,$http_method,$content_type="",$body="")
  947.     {
  948.         if($this->passcookies && $this->_redirectaddr)
  949.             $this->setcookies();
  950.  
  951.         $headers = array();  
  952.                    
  953.         $URI_PARTS = parse_url($URI);
  954.         if(empty($url))
  955.             $url = "/";
  956.         // GET ... header not needed for curl
  957.         //$headers[] = $http_method." ".$url." ".$this->_httpversion;      
  958.         if(!empty($this->agent))
  959.             $headers[] = "User-Agent: ".$this->agent;
  960.         if(!empty($this->host))
  961.             if(!empty($this->port))
  962.                 $headers[] = "Host: ".$this->host.":".$this->port;
  963.             else
  964.                 $headers[] = "Host: ".$this->host;
  965.         if(!empty($this->accept))
  966.             $headers[] = "Accept: ".$this->accept;
  967.         if(!empty($this->referer))
  968.             $headers[] = "Referer: ".$this->referer;
  969.         if(!empty($this->cookies))
  970.         {         
  971.             if(!is_array($this->cookies))
  972.                 $this->cookies = (array)$this->cookies;
  973.    
  974.             reset($this->cookies);
  975.             if ( count($this->cookies)> 0 ) {
  976.                 $cookie_str = 'Cookie: ';
  977.                 foreach ( $this->cookies as $cookieKey => $cookieVal ) {
  978.                 $cookie_str .= $cookieKey."=".urlencode($cookieVal)."; ";
  979.                 }
  980.                 $headers[] = substr($cookie_str,0,-2);
  981.             }
  982.         }
  983.         if(!empty($this->rawheaders))
  984.         {
  985.             if(!is_array($this->rawheaders))
  986.                 $this->rawheaders = (array)$this->rawheaders;
  987.             while(list($headerKey,$headerVal) = each($this->rawheaders))
  988.                 $headers[] = $headerKey.": ".$headerVal;
  989.         }
  990.         if(!empty($content_type)) {
  991.             if ($content_type == "multipart/form-data")
  992.                 $headers[] = "Content-type: $content_type; boundary=".$this->_mime_boundary;
  993.             else
  994.                 $headers[] = "Content-type: $content_type";
  995.         }
  996.         if(!empty($body))   
  997.             $headers[] = "Content-length: ".strlen($body);
  998.         if(!empty($this->user) || !empty($this->pass)) 
  999.             $headers[] = "Authorization: BASIC ".base64_encode($this->user.":".$this->pass);
  1000.            
  1001.         for($curr_header = 0; $curr_header <count($headers); $curr_header++) {
  1002.             $safer_header = strtr( $headers[$curr_header], "\"", " " );
  1003.             $cmdline_params .= " -H \"".$safer_header."\"";
  1004.         }
  1005.        
  1006.         if(!empty($body))
  1007.             $cmdline_params .= " -d \"$body\"";
  1008.        
  1009.         if($this->read_timeout> 0)
  1010.             $cmdline_params .= " -m ".$this->read_timeout;
  1011.        
  1012.         //$headerfile = tempnam($temp_dir, "sno");
  1013.         $headerfile = tempnam($this->temp_dir, "sno");
  1014.  
  1015.         $safer_URI = strtr( $URI, "\"", " " ); // strip quotes from the URI to avoid shell access
  1016.         exec($this->curl_path." -D \"$headerfile\"".$cmdline_params." \"".$safer_URI."\"",$results,$return);
  1017.        
  1018.         if($return)
  1019.         {
  1020.             $this->error = "Error: cURL could not retrieve the document, error $return.";
  1021.             return false;
  1022.         }
  1023.            
  1024.            
  1025.         $results = implode("\r\n",$results);
  1026.        
  1027.         $result_headers = file("$headerfile");
  1028.                        
  1029.         $this->_redirectaddr = false;
  1030.         unset($this->headers);
  1031.                        
  1032.         for($currentHeader = 0; $currentHeader <count($result_headers); $currentHeader++)
  1033.         {
  1034.            
  1035.             // if a header begins with Location: or URI:, set the redirect
  1036.             if(preg_match("/^(Location: |URI: )/i",$result_headers[$currentHeader]))
  1037.             {
  1038.                 // get URL portion of the redirect
  1039.                 preg_match("/^(Location: |URI:)\s+(.*)/",chop($result_headers[$currentHeader]),$matches);
  1040.                 // look for :// in the Location header to see if hostname is included
  1041.                 if(!preg_match("|\:\/\/|",$matches[2]))
  1042.                 {
  1043.                     // no host in the path, so prepend
  1044.                     $this->_redirectaddr = $URI_PARTS["scheme"]."://".$this->host.":".$this->port;
  1045.                     // eliminate double slash
  1046.                     if(!preg_match("|^/|",$matches[2]))
  1047.                             $this->_redirectaddr .= "/".$matches[2];
  1048.                     else
  1049.                             $this->_redirectaddr .= $matches[2];
  1050.                 }
  1051.                 else
  1052.                     $this->_redirectaddr = $matches[2];
  1053.             }
  1054.        
  1055.             if(preg_match("|^HTTP/|",$result_headers[$currentHeader]))
  1056.                 $this->response_code = $result_headers[$currentHeader];
  1057.  
  1058.             $this->headers[] = $result_headers[$currentHeader];
  1059.         }
  1060.  
  1061.         // check if there is a a redirect meta tag
  1062.        
  1063.         if(preg_match("'<meta[\s]*http-equiv[^>]*?content[\s]*=[\s]*[\"\']?\d+;[\s]*URL[\s]*=[\s]*([^\"\']*?)[\"\']?>'i",$results,$match))
  1064.         {
  1065.             $this->_redirectaddr = $this->_expandlinks($match[1],$URI)
  1066.         }
  1067.  
  1068.         // have we hit our frame depth and is there frame src to fetch?
  1069.         if(($this->_framedepth <$this->maxframes) && preg_match_all("'<frame\s+.*src[\s]*=[\'\"]?([^\'\"\>]+)'i",$results,$match))
  1070.         {
  1071.             $this->results[] = $results;
  1072.             for($x=0; $x<count($match[1]); $x++)
  1073.                 $this->_frameurls[] = $this->_expandlinks($match[1][$x],$URI_PARTS["scheme"]."://".$this->host);
  1074.         }
  1075.         // have we already fetched framed content?
  1076.         elseif(is_array($this->results))
  1077.             $this->results[] = $results;
  1078.         // no framed content
  1079.         else
  1080.             $this->results = $results;
  1081.  
  1082.         unlink("$headerfile");
  1083.        
  1084.         return true;
  1085.     }
  1086.  
  1087. /*======================================================================*\
  1088.     Function:   setcookies()
  1089.     Purpose:    set cookies for a redirection
  1090. \*======================================================================*/
  1091.    
  1092.     function setcookies()
  1093.     {
  1094.         for($x=0; $x<count($this->headers); $x++)
  1095.         {
  1096.         if(preg_match('/^set-cookie:[\s]+([^=]+)=([^;]+)/i', $this->headers[$x],$match))
  1097.             $this->cookies[$match[1]] = urldecode($match[2]);
  1098.         }
  1099.     }
  1100.  
  1101.    
  1102. /*======================================================================*\
  1103.     Function:   _check_timeout
  1104.     Purpose:    checks whether timeout has occurred
  1105.     Input:    $fp   file pointer
  1106. \*======================================================================*/
  1107.  
  1108.     function _check_timeout($fp)
  1109.     {
  1110.         if ($this->read_timeout> 0) {
  1111.             $fp_status = socket_get_status($fp);
  1112.             if ($fp_status["timed_out"]) {
  1113.                 $this->timed_out = true;
  1114.                 return true;
  1115.             }
  1116.         }
  1117.         return false;
  1118.     }
  1119.  
  1120. /*======================================================================*\
  1121.     Function:   _connect
  1122.     Purpose:    make a socket connection
  1123.     Input:    $fp   file pointer
  1124. \*======================================================================*/
  1125.    
  1126.     function _connect(&$fp)
  1127.     {
  1128.         if(!empty($this->proxy_host) && !empty($this->proxy_port))
  1129.             {
  1130.                 $this->_isproxy = true;
  1131.                
  1132.                 $host = $this->proxy_host;
  1133.                 $port = $this->proxy_port;
  1134.             }
  1135.         else
  1136.         {
  1137.             $host = $this->host;
  1138.             $port = $this->port;
  1139.         }
  1140.    
  1141.         $this->status = 0;
  1142.        
  1143.         if($fp = fsockopen(
  1144.                     $host,
  1145.                     $port,
  1146.                     $errno,
  1147.                     $errstr,
  1148.                     $this->_fp_timeout
  1149.                     ))
  1150.         {
  1151.             // socket connection succeeded
  1152.  
  1153.             return true;
  1154.         }
  1155.         else
  1156.         {
  1157.             // socket connection failed
  1158.             $this->status = $errno;
  1159.             switch($errno)
  1160.             {
  1161.                 case -3:
  1162.                     $this->error="socket creation failed (-3)";
  1163.                 case -4:
  1164.                     $this->error="dns lookup failure (-4)";
  1165.                 case -5:
  1166.                     $this->error="connection refused or timed out (-5)";
  1167.                 default:
  1168.                     $this->error="connection failed (".$errno.")";
  1169.             }
  1170.             return false;
  1171.         }
  1172.     }
  1173. /*======================================================================*\
  1174.     Function:   _disconnect
  1175.     Purpose:    disconnect a socket connection
  1176.     Input:    $fp   file pointer
  1177. \*======================================================================*/
  1178.    
  1179.     function _disconnect($fp)
  1180.     {
  1181.         return(fclose($fp));
  1182.     }
  1183.  
  1184.    
  1185. /*======================================================================*\
  1186.     Function:   _prepare_post_body
  1187.     Purpose:    Prepare post body according to encoding type
  1188.     Input:    $formvars  - form variables
  1189.                 $formfiles - form upload files
  1190.     Output:  post body
  1191. \*======================================================================*/
  1192.    
  1193.     function _prepare_post_body($formvars, $formfiles)
  1194.     {
  1195.         settype($formvars, "array");
  1196.         settype($formfiles, "array");
  1197.         $postdata = '';
  1198.  
  1199.         if (count($formvars) == 0 && count($formfiles) == 0)
  1200.             return;
  1201.        
  1202.         switch ($this->_submit_type) {
  1203.             case "application/x-www-form-urlencoded":
  1204.                 reset($formvars);
  1205.                 while(list($key,$val) = each($formvars)) {
  1206.                     if (is_array($val) || is_object($val)) {
  1207.                         while (list($cur_key, $cur_val) = each($val)) {
  1208.                             $postdata .= urlencode($key)."[]=".urlencode($cur_val)."&";
  1209.                         }
  1210.                     } else
  1211.                         $postdata .= urlencode($key)."=".urlencode($val)."&";
  1212.                 }
  1213.                 break;
  1214.  
  1215.             case "multipart/form-data":
  1216.                 $this->_mime_boundary = "Snoopy".md5(uniqid(microtime()));
  1217.                
  1218.                 reset($formvars);
  1219.                 while(list($key,$val) = each($formvars)) {
  1220.                     if (is_array($val) || is_object($val)) {
  1221.                         while (list($cur_key, $cur_val) = each($val)) {
  1222.                             $postdata .= "--".$this->_mime_boundary."\r\n";
  1223.                             $postdata .= "Content-Disposition: form-data; name=\"$key\[\]\"\r\n\r\n";
  1224.                             $postdata .= "$cur_val\r\n";
  1225.                         }
  1226.                     } else {
  1227.                         $postdata .= "--".$this->_mime_boundary."\r\n";
  1228.                         $postdata .= "Content-Disposition: form-data; name=\"$key\"\r\n\r\n";
  1229.                         $postdata .= "$val\r\n";
  1230.                     }
  1231.                 }
  1232.                
  1233. /*        reset($formfiles);
  1234.                 while (list($field_name, $file_names) = each($formfiles)) {
  1235.                     settype($file_names, "array");
  1236.                     while (list(, $file_name) = each($file_names)) {
  1237.                         if (!is_readable($file_name)) continue;
  1238.                         $fp = fopen($file_name, "r");
  1239.                         $file_content = fread($fp, filesize($file_name));
  1240.                         fclose($fp);
  1241.                         $base_name = basename($file_name);
  1242.                         $postdata .= "--".$this->_mime_boundary."\r\n";
  1243.                         $postdata .= "Content-Disposition: form-data; name=\"$field_name\"; filename=\"$base_name\"\r\n\r\n";
  1244.                         $postdata .= "$file_content\r\n";
  1245.                     }
  1246.                 }
  1247.                 $postdata .= "--".$this->_mime_boundary."--\r\n";
  1248.                 break;
  1249.         }
  1250. */
  1251.  
  1252. /*
  1253.    
  1254.     Using Form-based File Upload in Snoopy
  1255. ======================================
  1256. Snoopy is capable of handling form-based file uploads according to RFC's 1867
  1257. and 2388.  This note describes how to use Snoopy in a number of different file
  1258. upload scenarios.  Snoopy will handle multiple file upload fields per request
  1259. and multiple files per field.  Snoopy can also suggest a different filename in
  1260. the upload request from the "real" local filename.  Snoopy can also put
  1261. Content-type into the file upload request on a per file basis.
  1262. EXAMPLE 1: SIMPLE FILE UPLOAD
  1263. In this example there is a single field with a single file to be uploaded and
  1264. nothing fancy.  Note that it is necessary to call the set_submit_multipart()
  1265. function for the file upload to work.  The filename suggested to the server
  1266. will be "myfile.txt" since the path will be removed.
  1267.     include "Snoopy.class.inc";
  1268.     $snoopy = new Snoopy;
  1269.     $upload_url = "http://www.somedomain/upload.cgi";
  1270.     $upload_vars = array();
  1271.     $upload_files["FIELD1"] = "/home/me/myfile.txt";
  1272.     $snoopy->set_submit_multipart();
  1273.     if($snoopy->submit($upload_url, $upload_vars, $upload_files))
  1274.         echo "<PRE>".$snoopy->results."</PRE>\n";
  1275.     else
  1276.         echo "error with file upload: ".$snoopy->error."\n";
  1277. EXAMPLE 2: MULTIPLE FILES IN A SINGLE FIELD
  1278. Snoopy will support sending multiple files in response to a single form field.
  1279. This example works when sending multiple files to an Apache/PHP server.  Other
  1280. servers may not support this in quite the same way.
  1281.     include "Snoopy.class.inc";
  1282.     $snoopy = new Snoopy;
  1283.     $upload_url = "http://www.somedomain/upload.php";
  1284.     $upload_vars = array();
  1285.     $upload_files["FIELD1[]"] = array("/home/me/myfile1.txt", "/home/me/myfile2.txt");
  1286.     $snoopy->set_submit_multipart();
  1287.     if($snoopy->submit($upload_url, $upload_vars, $upload_files))
  1288.         echo "<PRE>".$snoopy->results."</PRE>\n";
  1289.     else
  1290.         echo "error with file upload: ".$snoopy->error."\n";
  1291. EXAMPLE 3: SPECIFYING FILENAMES and CONTENT TYPES
  1292. Some hosts are fussy about the filename that is passed to them by the file
  1293. upload request.  We can overcome this by getting Snoopy to suggest a different
  1294. filename in the request than the "real" local filename.  We can also get
  1295. Snoopy to specify an optional content type for each file.  This is achieved by
  1296. having each file entry be an array of parameters instead of a simple filename.
  1297.     include "Snoopy.class.inc";
  1298.     $snoopy = new Snoopy;
  1299.     $upload_url = "http://www.somedomain/upload.cgi";
  1300.     $upload_vars = array();
  1301.     $upload_files["FIELD1[]"] = array(
  1302.         array("name" => "/home/me/myfile1.txt",
  1303.               "remotename" => "C:\UPLOAD.TXT",
  1304.               "type" => "text/plain"),
  1305.         array("name" => "/home/me/myfile2.tiff",
  1306.               "remotename" => "C:\UPLOAD.TIF",
  1307.               "type" => "image/tiff")
  1308.         );
  1309.     $snoopy->set_submit_multipart();
  1310.     if($snoopy->submit($upload_url, $upload_vars, $upload_files))
  1311.         echo "<PRE>".$snoopy->results."</PRE>\n";
  1312.     else
  1313.         echo "error with file upload: ".$snoopy->error."\n";
  1314.     Esto resuelve el problema de que la clase snoopy no envia el tipo de imagen, asi que no rellena el parametro $_FILES["type"] que es necesario en muchas aplicaciones.
  1315. Despues de copiar es necesario perder el tiempo sustituyendo:
  1316. &quote;  por comillas dobles
  1317. &gt; por el smbolo mayor que
  1318. Ademas de corregir los saltos de linea.
  1319. Tambien hay que darse cuenta que es necesario cambiar la forma de llamar al metodo submit, ahora es necesario hacer arrays dentro de arrays para pasarle el parametro type.
  1320. ENGLISH
  1321. this fix the problem where not send de type of the files. But change the form of pass variables at method submit. Now i
  1322.    
  1323.     Submitted By:
  1324. Chris Davenport - chrisdavenport -> http://sourceforge.net/users/chrisdavenport/
  1325. */    
  1326.             reset($formfiles);
  1327.                 while (list($field_name, $file_names) = each($formfiles)) {
  1328.                     settype($file_names, "array");
  1329.                     //print_r($formfiles);
  1330.                     //echo '<br> fileNames: <br>';
  1331.                     //print_r($file_names);
  1332.                    
  1333.                     while (list(, $file_name) = each($file_names)) {
  1334.                         if (is_array($file_name)) {
  1335.                                 //if (!is_readable($file_name["name"])) continue;
  1336.                                 if (isset($file_name["remotename"]))
  1337.                                     $base_name = $file_name["remotename"];
  1338.                                 else
  1339.                                     $base_name =basename($file_name["name"]);
  1340.                                     $postdata .= "--".$this->_mime_boundary."\r\n";
  1341.                                
  1342.                                 $postdata .= "Content-disposition: form-data; name=\"$field_name\"; filename=\"$base_name\"\r\n";
  1343.                                
  1344.                                 //echo '<br>ESOY AQUI DENTRO<br>';
  1345.                                 //print_r($file_name);
  1346.                                 if ($file_name["type"]) $postdata .= "Content-type: ".$file_name["type"]."\r\n";
  1347.                                 //$postdata .= "Content-type: image/jpg \r\n";
  1348.                                
  1349.                                 /*$fp = fopen($file_name["name"], "r");
  1350.                                 $file_content = fread($fp, filesize($file_name["name"]));
  1351.                                 fclose($fp);*/
  1352.                                 $file_content= file_get_contents($file_name["name"]);
  1353.                                 $postdata .= "\r\n$file_content\r\n";
  1354.                         } else {
  1355.                             if (!is_readable($file_name))continue;
  1356.                             $fp = fopen($file_name, "r");
  1357.                             $file_content = fread($fp, filesize($file_name));
  1358.                             fclose($fp);
  1359.                             $base_name = basename($file_name);
  1360.                             $postdata .= "--".$this->_mime_boundary."\r\n";
  1361.                             $postdata .= "Content-Disposition: form-data; name=\"$field_name\";filename=\"$base_name\"\r\n\r\n";
  1362.                             $postdata .= "$file_content\r\n";
  1363.                         }
  1364.                     }
  1365.             }
  1366.             $postdata .= "--".$this->_mime_boundary."--\r\n";
  1367.             break;
  1368.  
  1369.         }
  1370.  
  1371.         return $postdata;
  1372.     }
  1373. }
  1374.  
  1375. ?>

para usar esta clase de envio de formularios un ejemplillo:

PHP:
  1. include('Snoopy.class.php');
  2. $envioForm= new Snoopy();
  3. $urlFoto1='http://www.tudominio.com/imagen.jpeg';
  4. $urlFoto2='http://www.tudominio.com/foto.png';
  5. $urlFoto3='http://www.tudominio.com/fotografias.jpeg';
  6. $urlFoto4='http://www.tudominio.com/imagenes.jpeg';
  7.  
  8. $envioForm->submit('http://www.urlEnvio.php',Array(
  9.                             'MAX_FILE_SIZE'=>'20971520',
  10.                             'variableFormulario1' =>'texto',
  11.                             'variableFormulario2' => '',
  12.                             'variableFormulario3' => '3',
  13.                             'variableFormulario4' => '',
  14.                             'variableFormulario3' =>'on',
  15.                             'submit'=> 'Enviar Datos'
  16.                                                    
  17.                             ), Array('archivo1'=> Array('0'=>Array('name'=>$urlFoto1,'remotename'=>'foto.jpeg','type'=>'image/jpeg')), 'archivo2'=> Array('0'=>Array('name'=>$urlFoto2,'remotename'=>'foto.jpeg','type'=>'image/jpeg')), 'archivo3'=> Array('0'=>Array('name'=>$urlFoto3,'remotename'=>'foto.jpeg','type'=>'image/jpeg')), 'archivo4'=> Array('0'=>Array('name'=>$urlFoto4,'remotename'=>'foto.jpeg','type'=>'image/jpeg'))));
  18.     //en este utltimo array enviamos las fotografias.

Fijaros que para enviar imagenes via post, es necesario hacer un array por cada fotografia con diferentes campos, entre elos, el nombre de la foto, el tipo de imangen, y la url de la imagen, que queremos que la libreria snoopy envie. Todos los arrays de las imagenes deberán ir dentro de un array con clave el nombre del campo del formulario "input type file" y como valor el array de parametros.

Esta clase en la linea 200 permite configurar las variables que queremos pasarle como puede ser sesiones, identificacion de usuario, etc... con esta clase podremos fingir un envio post de cualquier dato a una web.

cualquier duda, comentar..

permitir abrir ficheros externos desde php

Miércoles, 25 de Febrero de 2009

Queremos poder abrir ficheros de otro dominio, sin que nos de el error de permiso denegado por cross domain.
Para ello en php podemos activarlo con el siguiente linea para todo el escript:

PHP:
  1. ini_set("allow_url_fopen",1);// permitir abrir ficheros externos

php file_get_contents provoca 100% de CPU ocupada

Viernes, 20 de Febrero de 2009

Una única peticion a un servidor externo. Si este servidor tiene un tiempo de respuesta largo por motivos de mucho overlad, y por ello da tiempos de respuesta muy largos. Esto provoca Que el script que hace la peticion file_get_contents() ocupe el 100% de la CPU, durante todo el tiempo de espera. Hemos reportado el bug a php y estamos a la espera de que nos contesten.

Sistema Operativo donde aparece el error:
System Linux 2.6.9-55.0.9.ELsmp #1 SMP Thu Sep 27 18:28:00 EDT 2007 x86_64
PHP Version 5.2.6

más info en: http://bugs.php.net/bug.php?id=47461

Un ejemplo del código que provoca colgar el servidor.

PHP:
  1. <?php
  2.  
  3. //ini_set('max_execution_time',500); More time, More CPU 100%
  4.        
  5. $urlExternal =
  6. "http://www.webservicex.net/CurrencyConvertor.asmx/ConversionRate?FromCu
  7. rrency=EUR&ToCurrency=USD";
  8.    
  9. $oneString = file_get_contents($urlExternal);
  10. echo $oneString;
  11.  
  12. ?>

Realmente si este fallo es asi es un problema para todas aquellas páginas que recogen datos como tags, titles y otros, pudes provocarles problemas...

Alguien mas que se haya encontrado con este problema?

saludos.

desactivar el buffer de php, forzar la salida a pantalla flush()

Martes, 17 de Febrero de 2009

para ello será necesario hacer tres cosas:

definir en el php.ini output_buffering = 0
usar la instuccion flush() despues de cada salida a pantalla. Esto es incomodo, asi que podemos hacer uso de la funcion: ob_implicit_flush(true) que lo que hace es activar automaticamente un flush() despues de cada print y echo.
Además será necesario empeza definiendo un bufer ob_start(); al principio del codigo y cada vez que queramos forzar la salida al navegador utilizar un ob_flush().

asi tendremos un controld e poder enviar gran cantidad de información al navegador e ir viendola directamente sin tener que esperar.

Dos instrucciones a tener en cuenta cuando queremos mostrar salidas de datos html muy grandes por pantalla. Son las variables de inicio de php que limitan la memoria máxima de un script y su tiempo de ejecucion:
que corresponden a :

PHP:
  1. ini_set('max_execution_time',9000); //tiempo limite de ejecucion de un escript en segundos.
  2. ini_set("memory_limit","1500M"); // aumentamos la memoria a 1,5GB
  3. ini_set("buffering ","0"); // desactivando el buffer a salida estandar
  4.  
  5. for(i=0;i&lt;100000;i++){
  6. echo i;
  7.  
  8. ob_flush();// forzar la salida o control de la salida del texto al navegador con buffers.
  9.  
  10. flush();// opcion si no se usan buffers
  11.  
  12. sleep(20);
  13. }

esto va bien para minotorizar procesos largos de mirgración de datos, parseos extremadamente largos, etc.

el problema es cuando itentas hacer un flush justa antes de un file_get_contents(), que suele relentizar la salida a pantalla. Asi consigues verlo todo cuando toca.

Editado 16-11-2009:

No he comentado, que en segun que navegadores es necesario, que el código de salida tenga las cabeceras correctas asi incluir las cabeceras, y el cuerpo antes de hacer los "echos" o prints por pantalla.

una posible cabecera:

HTML:
  1. &lt;!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
  2. "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"&gt;
  3. &lt;html xmlns="http://www.w3.org/1999/xhtml" lang="es" xml:lang="es"&gt;
  4. &lt;head&gt;
  5. &lt;meta http-equiv="Content-Type" content="text/html; charset=UTF-8" /&gt;
  6. &lt;/head&gt;
  7. &lt;body&gt;

acordaos de cerrar los tags body y html despues de las salidas a pantalla