Posts etiquetados ‘server’


You can read the English version of this post in http://phpsblog.agustinvillalba.com/objects-and-references-in-memory-in-php/

Hoy vamos a hablar sobre cómo PHP crea los objetos en memoria cuando realizamos una instrucción del tipo $a = new Foo(); y sobre cómo son gestionadas las referencias en memoria, dado que este es un tema que puede generar debate y diferencia de opiniones. Para ello hablaremos de lo qué NO son las referencias en PHP. Por último, veremos cómo funciona el recolector de basura (o garbage collector) en PHP.

Objetos y referencias en PHP

Una afirmación que está muy extendida en los libros de PHP, y en la red en general, es que en PHP los objetos, por defecto, se pasan por referencia. También hay quienes dicen que los objetos en PHP se asignan por copia. Estas afirmaciones no son completamente ciertas, y para comprobarlo primero hemos de analizar qué son (y qué NO son) las referencias en PHP.

Qué NO son las referencias en PHP

Creo que más importante que saber qué son las referencias en PHP, hemos de aclarar qué NO son las referencias en PHP. En PHP las referencias no son punteros al estilo C, no podemos realizar operaciones aritméticas con las referencias como se puede hacer en C. ¿Por qué? Porque en PHP las referencias no son en realidad direcciones de memoria como en C, no son números que indican una posición de memoria. Pero entonces… ¿qué son en realidad las referencias?

Qué son las referencias en PHP

En PHP, las referencias son «alias» que permiten que 2 variables distintas puedan escribir sobre un mismo valor. O visto de otra manera, son un mecanismo que nos permiten acceder un mismo valor desde nombre de variables distintos y que se comporten como si fueran la misma variable. Hay que tener en cuenta que, en PHP, el nombre de la variable y el contenido de esa variable son 2 cosas totalmente distintas que se enlazan en lo que se llama la tabla de símbolos. De forma que cuando creamos una referencia, simplemente se está añadiendo un alias de dicha variable en la tabla de símbolos de PHP. Veámoslo con un ejemplo, supongamos que tenemos el siguiente código:

$a = new Foo();

Cuando se ejecuta la instrucción anterior, realmente lo que está sucediendo es que se crea una variable «a» en memoria, se crea un objeto de tipo Foo en memoria y se añade una entrada en la tabla de símbolos de PHP en la que se indica que la variable $a «referencia» (o se relaciona, o «apunta», o como se quiera llamar) al objeto Foo, pero NO es un puntero a dicho objeto. Si a continuación ejecutamos la instrucción:

$b = $a;

Lo que ocurre no es que se $b se convierta en una referencia de $a, tampoco se puede decir que $b sea una copia de $a. Lo que realmente ha sucedido es que se ha creado una nueva variable «b» en memoria y luego se ha añadido una nueva entrada en la tabla de símbolos indicando que la variable $b, también «referencia» al mismo objeto Foo que $a. Si a continuación ejecutamos la instrucción:

$c = &$a;

Lo que ocurre es que en memoria se habrá creado una tercera variable «c» pero NO se añade una nueva entrada en la tabla de símbolos para «c», sino que en la tabla de símbolos se indica que «c» es un alias de «a», por lo tanto se comportará de forma idéntica que esta, pero no es que «c» sea un puntero a «a» (lo que en C se conoce como punteros a punteros).
Veamos un ejemplos más completo:

<?php

class myClass {
    public $var;
		
    function __construct() {
	$this->var = 1;
    }

    function inc() { return ++$this->var; }
}

$a = new myClass(); // $a "referencia" a un objeto Foo
$b = $a; //b también referencia al mismo objeto Foo que a
//($a) == ($b) == <id> del objeto Foo, pero a y b son entradas distintas en la tabla de símbolos

echo "\$a = ";var_dump($a);
echo "\$b = ";var_dump($b);

$c = &$a; //$c es un alias de $a
//($a, $c) == <id> del objeto Foo, c es un alias de a en la tabla de símbolos
echo "\$c = ";var_dump($c);

$a = NULL;
//Se elimina la entrada en la tabla de símbolos donde se relacionaba a "$a" con el objeto Foo
//Al eliminarse esta entrada, $c también deja de estar relacionado con Foo
//A todos los efectos, Foo sigue existiendo en memoria, y sigue estando relacionado con $b
echo "\$a = ";var_dump($a);
echo "\$b = ";var_dump($b);
echo "\$c = ";var_dump($c);
echo "\$b->var: ".$b->inc();
echo "\$b->var: ".$b->inc();

$b = NULL;
//Se elimina la entrada en la tabla de símbolos donde se relacionaba a "$b" con el objeto Foo
//Ya no hay más entradas en la tabla de símbolos que se relacionen con Foo,
//Por lo que Foo ha dejado de estar referenciado y puede ser eliminado por el garbage collector

echo "\$b = ";var_dump($b);

Las salidas que produce la ejecución del script anterior son:

$a = object(myClass)#1 (1) { ["var"]=> int(1) } 
$b = object(myClass)#1 (1) { ["var"]=> int(1) } 

$c = object(myClass)#1 (1) { ["var"]=> int(1) } 
$a = NULL 
$b = object(myClass)#1 (1) { ["var"]=> int(1) } 
$c = NULL 
$b->var: 2
$b->var: 3

$b = NULL

Garbage collector en PHP

Por último, veamos cómo funciona el garbage collector (o recolector de basura) en PHP. Un objeto o una variable en PHP podrá ser eliminada de memoria por el garbage collector cuando no exista ninguna referencia a dicho objeto en la tabla de símbolos. Es decir, PHP mantiene un contador de referencias a un objeto desde el momento en que éste es creado, de forma que durante la ejecución del script PHP va incrementando y decrementando dicho contador de referencias en función de las variables que le van «apuntando». Una vez ese contador de referencias llega a 0 (es decir, nadie está relacionado con ese objeto y por lo tanto, no se está utilizando dicho objeto), PHP marca ese objeto como basura o eliminable, de forma que en la siguiente pasada del garbage collector, éste eliminará dicho objeto de memoria y esa posición de memoria será utilizable por PHP nuevamente.

De esta forma esperamos haber aclarado un poco más cómo gestiona PHP los objetos y variables en memoria y cómo se «seleccionan» los objetos que han de ser eliminados por el recolector de basura en PHP.

You can read the English version of this post in http://phpsblog.agustinvillalba.com/objects-and-references-in-memory-in-php/


You can read the English version of this post in http://phpsblog.agustinvillalba.com/upload-progress-bar-in-codeigniter-without-flash/

Hoy vamos a ver cómo podemos crearnos una barra de progreso de subida de archivos en CodeIgniter sin la necesidad de recurrir a librerías o plug-ins hechos en Flash (del tipo SWFUpload, etc) que escapan a nuestro control, dado que habitualmente estas librerías nos ofrecen los archivos .swf ya compilados, por lo que nos es imposible modificar nada en ellos, en el caso de que tengamos conocimientos de programación en ActionScript 2 o 3.

Antes que nada hemos de decir que crear una barra de progreso de subida de archivos en PHP no es tan sencillo como pudiera parecer. El primer problema es que las versiones de PHP anteriores a la 5.2 no ofrecen las herramientas necesarias para poder ofrecer información sobre cómo la subida del archivo en cada momento. El segundo problema es que AJAX, por sí solo, no nos permite consultar el estado de la subida del archivo, dado que, por razones de seguridad obvias, JavaScript no tiene acceso a los archivos del sistema operativo del cliente, por lo que necesitaremos un «truco» utilizando un iframe.

(más…)


You can read the English version of this post in http://phpsblog.agustinvillalba.com/automatic-configuration-of-url-in-codeigniter/

En este mini-post voy a explicar cómo configurar nuestro CodeIgniter para que funcione en cualquier servidor sin tener que estar modificando los parámetros de configuración de la «base_url». De esta forma, podemos trasladar nuestra versión de desarrollo a nuestro servidor de producción sin preocuparnos de tener que cambiar nada en la configuración. Para esto lo único que tenemos que hacer es modificar el siguiente código en nuestro archivo system/application/config/config.php:

$config['base_url'] = ((isset($_SERVER['HTTPS']) && $_SERVER['HTTPS'] == "on") ? "https" : "http");
$config['base_url'] .= "://".$_SERVER['HTTP_HOST'];
if (!isset($_SERVER['ORIG_SCRIPT_NAME']))
{
  $config['base_url'] .= str_replace(basename($_SERVER['SCRIPT_NAME']),"",$_SERVER['SCRIPT_NAME']);
}
else
{
  $config['base_url'] .= str_replace(basename($_SERVER['ORIG_SCRIPT_NAME']),"",$_SERVER['ORIG_SCRIPT_NAME']);
}

Con este sencillo código ya podemos trasladar nuestra apliación sin necesidad de preocuparnos de configurar correctamente su URL.

You can read the English version of this post in http://phpsblog.agustinvillalba.com/automatic-configuration-of-url-in-codeigniter/


You can read the English version of this post in http://phpsblog.agustinvillalba.com/creating-a-soap-server-in-codeigniter/

Tal y como nos pedía nuestro amigo Enrique, y porque creo que no será el único que pueda tener esta duda, hoy voy a hablar sobre cómo crear un servidor de servicios web con NuSOAP en CodeIgniter. Para ello partiré de la base que establecimos en el post anterior (Utilizando NuSOAP en CodeIgniter), por lo que les recomiendo leer ese post antes de continuar con este, dado que aquí utilizaremos la «pseudo» librería nuSoap_lib que creamos anteriormente.
(más…)


You can read the English version of this post in http://phpsblog.agustinvillalba.com/exporting-a-drupal-site/

Hace unos días me vi en la necesidad de exportar desde mi servidor local al servidor de desarrollo on-line (dado que el trabajo es en equipo) un sitio desarrollado con el gestor de contenidos Drupal , para continuar el trabajo en grupo desde un único servidor, evitando así que el sitio evolucione de forma dispar en el servidor local de cada miembro del equipo de desarrollo. Investigando en la red he encontrado poca información y muy dispersa, de forma que me pareció útil ponerla toda junta en un único post.

(más…)