<?xml version="1.0" encoding="UTF-8"?>
<?xml-stylesheet type="text/xsl" media="screen" href="/~d/styles/atom10full.xsl"?><?xml-stylesheet type="text/css" media="screen" href="http://feeds.feedburner.com/~d/styles/itemcontent.css"?><feed xmlns="http://www.w3.org/2005/Atom" xmlns:openSearch="http://a9.com/-/spec/opensearch/1.1/" xmlns:georss="http://www.georss.org/georss" xmlns:thr="http://purl.org/syndication/thread/1.0" xmlns:gd="http://schemas.google.com/g/2005" gd:etag="W/&quot;CkYMQX08eSp7ImA9WxFaGEU.&quot;"><id>tag:blogger.com,1999:blog-1250738086120444710</id><updated>2010-07-23T12:16:20.371+02:00</updated><title>phpElegante</title><subtitle type="html">Técnicas y consejos avanzados de programación en PHP</subtitle><link rel="http://schemas.google.com/g/2005#feed" type="application/atom+xml" href="http://php.soywiz.com/feeds/posts/default" /><link rel="alternate" type="text/html" href="http://php.soywiz.com/" /><author><name>soywiz</name><email>noreply@blogger.com</email></author><generator version="7.00" uri="http://www.blogger.com">Blogger</generator><openSearch:totalResults>20</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="self" type="application/atom+xml" href="http://feeds.feedburner.com/Phpelegante" /><feedburner:info xmlns:feedburner="http://rssnamespace.org/feedburner/ext/1.0" uri="phpelegante" /><atom10:link xmlns:atom10="http://www.w3.org/2005/Atom" rel="hub" href="http://pubsubhubbub.appspot.com/" /><entry gd:etag="W/&quot;D08NSX04eyp7ImA9WxFaEU0.&quot;"><id>tag:blogger.com,1999:blog-1250738086120444710.post-3852161850671640842</id><published>2010-07-14T12:55:00.008+02:00</published><updated>2010-07-14T13:11:38.333+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-07-14T13:11:38.333+02:00</app:edited><title>Referencias en PHP y funciones útiles auxiliares</title><content type="html">Uno de los aspectos interesantes de PHP es la gestión de referencias.&lt;br /&gt;
Como es bien sabido en PHP, intentar acceder a una variable o una clave en un array que no existe produce un notice y generalmente hay que estar tratando continuamente con isset y con bastantes código redundante.&lt;br /&gt;
El caso es que PHP permite crear una referencia a una variable inexistente para crearla a posteriori. Es como crear un slot de la variable en potencia y asignarlo si así se decide. También permite comprobar la existencia de la variable referenciada usando la variable de referencia.&lt;br /&gt;
&lt;br /&gt;
Es bastante típico en PHP querer obtener el valor de una variable si existe, o un valor por defecto en el caso de que no exista. Ejemplo:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;$page = isset($_GET['page']) ? $_GET['page'] : 1;&lt;/pre&gt;&lt;br /&gt;
En PHP 5.3 se añadió un shortcut del operador ternario. A priori parecía bastante interesante, porque teóricamente hubiese podido permitir hacer esto: $page = $_GET['page'] ?: 1;&lt;br /&gt;
Pero resulta que la cagaron estrepitosamente. Resulta que lo que hace el shortcutdel ternario es evaluar la parte de la izquierda y si al castear implícitamente a bool, el resultado es false, se devuelve el resultado de la expresión de la derecha. Esto para empezar no evita el tema de los notices al intentar acceder a una clave inexistente en el array. Además hay un pequeño matiz que difiere con el isset. Y es que si la variable existe pero tiene un valor evaluado como false (como una cadena vacía o el valor 0), ya se estaría devolviendo lo de la derecha. Y generalmente no es lo deseado.&lt;br /&gt;
Así que veo completamente inútil esta adición al PHP 5.3.&lt;br /&gt;
&lt;br /&gt;
Sin embargo PHP y sus referencias permiten crear funciones auxiliares que permiten resolver estos problemas con facilidad y evitando repetir la variable dos veces:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;$page = isset_default($_GET['page'], 1);&lt;/pre&gt;&lt;br /&gt;
Ésto es posible sin notices porque en las últimas versiones de PHP especificas los valores que se pasan por referencia en la propia descripción de la función. Así pues:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;function isset_default(&amp;amp;$var, $default) {
    return isset($var) ? $var : $default;
}&lt;/pre&gt;&lt;br /&gt;
Esto vendría a ser como una macro bastante útil.&lt;br /&gt;
&lt;br /&gt;
También es bastante común comprobar la existencia de varias claves en un array.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;if (isset($_GET['a'], $_GET['b'], $_GET['c'])) { }&lt;/pre&gt;-&amp;gt;&lt;br /&gt;
&lt;pre&gt;if (isset_array($_GET, array('a', 'b', 'c'))) { }&lt;/pre&gt;&lt;br /&gt;
Aquí la referencia evita que PHP duplique un array potencialmente grande.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;function isset_array(array &amp;amp;$array, array $keys) {
    foreach ($keys as $key) if (!isset($array[$key])) return false;
    return true;
}&lt;/pre&gt;&lt;br /&gt;
Otro patrón común que se puede resolver con macros de referencias es hacer un cambio a posteriori de una variable.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;function method() {
    if ($this-&amp;gt;alreadyPerformed) return;
    $this-&amp;gt;alreadyPerformed = true;
    ...
}&lt;/pre&gt;-&amp;gt;&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;function method() {
    if (post_assign($this-&amp;gt;alreadyPerformed, true)) return;
    ...
}&lt;/pre&gt;&lt;br /&gt;
&lt;pre&gt;function post_assign(&amp;amp;$var, $value) {
    $last_value = $var;
    $var = $value;
    return $last_value;
}&lt;/pre&gt;&lt;br /&gt;
&lt;br /&gt;
En este caso concreto también se podría usar el pequeño truco de usar enteros para evitar tener la variable dos veces referenciada. Y usar el operador unario del postincremento:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;function method() {
    if ($this-&amp;gt;alreadyPerformed++) return;
    ...
}&lt;/pre&gt;&lt;br /&gt;
Hay muchas formas útiles de usar las referencias en PHP. Por ejemplo para tener una caché temporal en memoria muy ligera:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;static function cached_method($key) {
    static $cache = array();
    $result = &amp;amp;$cache[$key];
    if (!isset($result)) {
        // ...
    }
    return $result;
}&lt;/pre&gt;&lt;br /&gt;
Con referencias y PHP 5.3:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;function &amp;amp;cache_result(&amp;amp;$var, $func) {
    if (!isset($var)) $var = $func();
    return $var;
}&lt;/pre&gt;&lt;br /&gt;
&lt;pre&gt;static function cached_method($key) {
    static $cache = array();
    return cache_result($cache[$key], function() use ($key) {
         // ...
    });
}
&lt;/pre&gt;&lt;br /&gt;
Otras funciones que considero útiles aunque no tengan que ver directamente con referencias:&lt;br /&gt;
&lt;br /&gt;
Por ejemplo si queremos obtener una array a partir de otro sin las claves que empiezan por _:&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;$array = array_filter_keys($_GET, function($key) { return substr($key, 0, 1) != '_'; } );&lt;/pre&gt;&lt;br /&gt;
&lt;pre&gt;function array_filter_keys(&amp;$array, $callback) {
    $result = array();
    foreach ($array as $key =&gt; $value) {
        if ($callback($key, $value)) $result[$key] = $value;
    }
    return $result;
}&lt;/pre&gt;&lt;br /&gt;
En determinadas ocasiones queremos ver un array visualmente que contiene html. Con xdebug la functión var_dump puede estar coloreada. Pero ni siempre está disponible el xdebug, ni tampoco es siempre lo más cómodo visualmente. Aquí hay una función que permite mostrar un print_r para html. Haciendo uso del tag pre y del escapado de html.&lt;br /&gt;
&lt;br /&gt;
&lt;pre&gt;function print_r_pre($var) {
    echo '&amp;lt;pre&amp;gt;';
    echo htmlspecialchars(print_r($var, true));
    echo '&amp;lt;/pre&amp;gt;';
}&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1250738086120444710-3852161850671640842?l=php.soywiz.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/9xK0wLebwlBxWbiHE5I3Bwt0xCw/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/9xK0wLebwlBxWbiHE5I3Bwt0xCw/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/9xK0wLebwlBxWbiHE5I3Bwt0xCw/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/9xK0wLebwlBxWbiHE5I3Bwt0xCw/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://php.soywiz.com/feeds/3852161850671640842/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://php.soywiz.com/2010/07/referencias-en-php-y-funciones-utiles.html#comment-form" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1250738086120444710/posts/default/3852161850671640842?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1250738086120444710/posts/default/3852161850671640842?v=2" /><link rel="alternate" type="text/html" href="http://php.soywiz.com/2010/07/referencias-en-php-y-funciones-utiles.html" title="Referencias en PHP y funciones útiles auxiliares" /><author><name>soywiz</name><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03708515771492521927" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;CkQAQn49cCp7ImA9WxFWFEU.&quot;"><id>tag:blogger.com,1999:blog-1250738086120444710.post-3668457674584609364</id><published>2010-06-02T13:13:00.010+02:00</published><updated>2010-06-02T14:05:43.068+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-06-02T14:05:43.068+02:00</app:edited><title>Trabajando con objetos en base de datos con PDO y Mongo + Demo con Twig</title><content type="html">&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Trabajar con resultados de bases de datos como si fuesen objetos permite trabajar de una forma muy cómoda e intuitiva. PDO tiene soporte nativo para devolver instancias de una clase en vez de arrays. Pero con MongoDB tampoco es mucho más complicado conseguir un iterador de objetos de una clase determinada.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;Aquí coloco un ejemplo con PDO, Mongo y Twig. Con twig se ve claramente la comodidad de tener objetos con los que poder llamar métodos que produzcan datos derivados sin tenerlos que generar explícitamente (on demand).&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;He creado una clase derivada de IteratorIterator y un método estático usando late static binding para poder castear un array/objeto a una nueva instancia de una clase especificada.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt; &lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman';"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;pre class="phpcode" style="background-attachment: initial; background-clip: initial; background-color: white; background-image: initial; background-origin: initial; background-position: initial initial; background-repeat: initial initial; color: black; font: normal normal normal 10pt/normal Consolas;"&gt;&lt;span class="Apple-style-span" style="color: blue;"&gt;&lt;span class="Apple-style-span" style="color: black; font-family: 'Times New Roman'; font-size: medium; white-space: normal;"&gt;

&lt;pre class="phpcode" style="background-attachment: initial; background-clip: initial; background-color: white; background-image: initial; background-origin: initial; background-position: initial initial; background-repeat: initial initial; color: black; font: normal normal normal 10pt/normal Consolas;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Times New Roman'; font-size: medium; white-space: normal;"&gt;
&lt;pre class="phpcode" style="background-attachment: initial; background-clip: initial; background-color: white; background-image: initial; background-origin: initial; background-position: initial initial; background-repeat: initial initial; color: black; font: normal normal normal 10pt/normal Consolas;"&gt;class CastModelIteratorIterator extends IteratorIterator {
    public $class;

    function current() {
        return Model::cast(parent::current(), $this-&amp;gt;class);
    }
}

class Model {
    static public function cast($array, $class = null) {
        $object = ($class === null) ? (new static) : (new $class);
        foreach ($array as $k =&amp;gt; $v) $object-&amp;gt;$k = $v;
        return $object;
    }
    
    static public function castIterator($iterator) {
        $iterator = new CastModelIteratorIterator($iterator);
        $iterator-&amp;gt;class = get_called_class();
        return $iterator;
    }
}

class TestModel extends Model {
    public $name, $pass;

    function __construct($name = 'test') {
        $this-&amp;gt;name = $name;
        $this-&amp;gt;pass = self::hashPassword('test');
    }
    static function hashPassword($password) {
        return md5("{$password}*");
    }
    function checkPassword($password) {
        return $this-&amp;gt;pass == self::hashPassword($password);
    }
    function url() {
        return sprintf('/user/%s', urlencode($this-&amp;gt;name));
    }
}

// Sqlite PDO Test
{
    $db = new PDO('sqlite::memory:');
    $db-&amp;gt;query('CREATE TABLE TestModel (name, pass);');
    $t = $db-&amp;gt;prepare('INSERT INTO TestModel (name, pass) VALUES (?, ?);');
    $model = new TestModel('Test');
    $t-&amp;gt;execute(array($model-&amp;gt;name, $model-&amp;gt;pass));
    foreach ($db-&amp;gt;query('SELECT * FROM TestModel;', PDO::FETCH_CLASS, 'TestModel') as $e) {
        printf("%s\n", $e-&amp;gt;url());
    }
}

// Mongo Test
{
    $mongo = new Mongo(); // connect
    $db = $mongo-&amp;gt;demo;
    $collection = $db-&amp;gt;TestModel;
    $collection-&amp;gt;remove();
    $collection-&amp;gt;insert(new TestModel('Test'));

    foreach (TestModel::castIterator($collection-&amp;gt;find()) as $e) {
        printf("%s\n", $e-&amp;gt;url());
    }
}

// Twig
{
    require_once(__DIR__ . '/Twig/Autoloader.php');
    Twig_Autoloader::register();
    $collection-&amp;gt;insert(new TestModel('Demo'));

    $twig = new Twig_Environment(new Twig_Loader_String(), array(
        'debug'       =&amp;gt; true,
        'auto_reload' =&amp;gt; true,
    ));

    $twig-&amp;gt;loadTemplate('
        &amp;lt;ul&amp;gt;{% for item in list %}
&amp;lt;li&amp;gt;&amp;lt;a href="{{ item.url }}"&amp;gt;User {{ item.name }}&amp;lt;/a&amp;gt;&amp;lt;/li&amp;gt;
{% endfor %}&amp;lt;/ul&amp;gt;
')-&amp;gt;display(array(
        'list' =&amp;gt; TestModel::castIterator($collection-&amp;gt;find()),
    ));
}&lt;/pre&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1250738086120444710-3668457674584609364?l=php.soywiz.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Uq74YGYDGf-wJIEG9hx530LpC90/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Uq74YGYDGf-wJIEG9hx530LpC90/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Uq74YGYDGf-wJIEG9hx530LpC90/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Uq74YGYDGf-wJIEG9hx530LpC90/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://php.soywiz.com/feeds/3668457674584609364/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://php.soywiz.com/2010/06/trabajando-con-objetos-en-base-de-datos.html#comment-form" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1250738086120444710/posts/default/3668457674584609364?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1250738086120444710/posts/default/3668457674584609364?v=2" /><link rel="alternate" type="text/html" href="http://php.soywiz.com/2010/06/trabajando-con-objetos-en-base-de-datos.html" title="Trabajando con objetos en base de datos con PDO y Mongo + Demo con Twig" /><author><name>soywiz</name><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03708515771492521927" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;DUMNSHs6eyp7ImA9WxFWFE8.&quot;"><id>tag:blogger.com,1999:blog-1250738086120444710.post-9168809400545835818</id><published>2010-06-01T23:22:00.001+02:00</published><updated>2010-06-01T23:24:59.513+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-06-01T23:24:59.513+02:00</app:edited><title>Trabajando con archivos binarios en PHP</title><content type="html">Aunque PHP no es un lenguaje de programación muy adecuado para trabajar con archivos binarios, en determinadas circunstancias puede ser de utilidad. Y explicaré aquí algunos detalles a tener en cuenta al trabajar con archivos binarios y técnicas para hacerlo con sencillez.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;fopen. Flag 'b' para binarios en windows.&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
A la hora de abrir archivos, existen diversos modos: de escritura (write only), de lectura (read only), de lectura/escritura (read/write), de escritura situando el cursor al final del archivo (append). Además hay un flag que permite especifica si el archivo a abrir se usará como un archivo de texto o como uno binario. En modo texto es posible que un salto de línea (\n) se guarde como dos bytes \r\n dependiendo del sistema operativo. Y esto puede causar archivos corruptos en muchos casos. Nota: El flag opuesto a 'b' es 't'. Puede producir problemas también con ftell. Se recomiendo usar siempre el flag 'b' para que la compatibilidad sea la misma indistintamente de la plataforma.&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;pack, chr /&amp;nbsp;unpack + list, ord&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
Estas funciones sirven para empaquetar y desempaquetar valores numéricos y cadenas en datos binarios. Y son el pilar fundamental de una codificación/decodificación fácil y cómoda:&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;a href="http://es.php.net/ord"&gt;ord &lt;/a&gt;&lt;/b&gt;(ordinal) obtiene el valor numérico que tiene un carácter. Se le pasa una cadena y lo calcula a partir del primer byte de la cadena&lt;br /&gt;
&lt;b&gt;&lt;a href="http://draft.blogger.com/goog_1966246566"&gt;chr&lt;/a&gt;&lt;/b&gt;&lt;a href="http://es.php.net/chr"&gt; &lt;/a&gt;(character) obtiene el carácter de un valor numérico (la función inversa a ord).&lt;br /&gt;
Ambas funciones trabajan a nivel de byte y únicamente trabajan con el rango de 00-FF.&lt;br /&gt;
&lt;br /&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;chr(ord('a')) == 'a'&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;b&gt;&lt;a href="http://php.net/pack"&gt;pack&lt;/a&gt;&lt;/b&gt;&lt;a href="http://es.php.net/pack"&gt; &lt;/a&gt;permite empaquetar una serie de valores en un formato binario. La función proviene de perl. Se le pasa una cadena con el formato de empaquetado y luego una sucesión de parámetros con los valores a empaquetar. El formato de empaquetado contempla valores con signo y sin signo de 8, 16 y 32 bits pudiendo especificar el endian: usando el de la máquina actual, o usando little o big endian. También permite empaquetar cadenas terminadas con '\0's o con espacios.&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;b&gt;&lt;a href="http://php.net/unpack"&gt;unpack&lt;/a&gt;&lt;/b&gt;&lt;a href="http://es.php.net/unpack"&gt;&amp;nbsp;&lt;/a&gt;permite desempaquetar una serie de valores a partir de una cadena binaria. Si no se especifican nombres para los datos desempaquetados, se devuelve un array de claves numéricas empezando por la clave 1 (en vez de por la clave 0). Para extraer valores en variables con comodidad se puede usar la estructura del lenguaje "list". Teniendo en cuenta que el casting de array a bool es siempre true, se puede usar una asignación intrínseca y el operador ternario para hacer una extracción en una única expresión.&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;list(, $valor) = unpack('s', "\xFF\xFF");&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;list($valor) = array_values(unpack('s', "\xFF\xFF"));&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;$valor = ($v = unpack('s', "\xFF\xFF")) ? $v[1] : false;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;echo $valor;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;Tip:&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;b&gt;pack('H*', '736f7977697a')&lt;/b&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;Las funciones pack usando H*, permiten convertir datos en hexadecimal a cadenas binarias y viceversa. (ver funciones &lt;b&gt;hex&lt;/b&gt;/&lt;b&gt;unhex &lt;/b&gt;de las funcionesde utilidad del final del artículo)&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;br /&gt;
&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;&lt;b&gt;fseek (archivos grandes)&lt;/b&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
PHP trabaja con dos tipos numéricos: signed int (32 bits) y double (64 bits) de los cuales se pueden conseguir 53 bits para valores enteros (sin decimales) que son unos 16 digitos decimales.&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;$a = 0x7FFFFFFF; var_dump($a); $a++; var_dump($a);&amp;nbsp;var_dump((int)$a);&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;int(2147483647)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;float(2147483648)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;int(-2147483648)&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
El problema es que fseek trabaja con enteros de 32 bits y el direccionamiento de fseek y ftell de archivos está limitado a eso en PHP. Que son 2GB sin signo y 4GB con signo. Diría que se puede superar este límite haciendo varias llamadas con SEEK_CUR.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;substr&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
&lt;br /&gt;
La función substr nos permite extraer determinados bytes de una cadena binaria como si fuese una cadena de texto normal. Donde cada caracter es un byte.&lt;br /&gt;
&lt;br /&gt;
Nota:&lt;br /&gt;
En la configuración de PHP hay una opción llamada "mbstring.func_overload" que permite susitutir las funciones normales. Esto permite hacer que las funciones normales para trabajar con cadenas se sustituyan por sus equivalentes mb_*. Esto es un problema que puede llevar a verdaderos quebraderos de cabeza cuando se trabaja con cadenas binarias.&lt;br /&gt;
&lt;br /&gt;
Una solución pasa por:&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;$back_encoding =&amp;nbsp;mb_internal_encoding();&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;mb_internal_encoding('8bit');&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;// Hacer cosas.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;mb_internal_encoding($back_encoding);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;
O directamente utilizar las funciones mb_* usando 8bit como el encoding normal.&lt;br /&gt;
Así que para extraer los primeros 10 bytes:&lt;br /&gt;
substr($cadena, 0, 10);&lt;br /&gt;
-&amp;gt;&lt;br /&gt;
mb_substr($cadena, 0, 10, '8bit');&lt;br /&gt;
&lt;br /&gt;
Con el resto de funciones de cadena tipo strlen pasa exáctamente lo mismo.&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;&lt;b&gt;acceso como array [] {}&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
PHP permite acceder a las cadenas como si fuesen arrays. Tanto para lectura como para escritura.&lt;br /&gt;
Así que:&lt;br /&gt;
$str = 'abc';&lt;br /&gt;
$str[1] == substr($str, 1, 1);&lt;br /&gt;
&lt;br /&gt;
$str[1] = 'a';&lt;br /&gt;
$str = substr_replace($str, 'a', 1, 1);&lt;br /&gt;
&lt;br /&gt;
$str == 'aac'&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;&lt;b&gt;streams: php://memory, php://temp, data://, file_get_contents&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
En lenguajes que soportan&amp;nbsp;slicing de streams, leer y procesar archivos binarios suele ser bastante mas cómodo. PHP no soporta slicing de streams directamente, y aunque se puede hacer un apaño, no se soporta nativamente. Sin embargo la lectura secuencial de datos y el "consumo" de datos es un patrón básico en el procesado de archivos binarios medianamente complejos. Los streams son muy cómodos para la consumición de datos ya que tiene un cursor y un torrente de datos y cada vez que lees, se actualiza ese cursor. En determinadas ocasiones tendremos los datos que queremos consumir en una cadena binaria, por ejemplo tras obtenerlos directamente con file_get_contents, tras generarlos por otro medio o al leer un subtream en una cadena.&lt;br /&gt;
Una función que puede permitir la consumición de datos en una cadena podría ser esta:&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;function fread_str(&amp;amp;$str, $len) { $data = substr($str, 0, $len); $str = substr($str, $len); return $data; }&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
Aunque esta forma de procesar datos es muy poco eficiente. Porque estás reconstruyendo una cadena todo el rato, copiando datos contínuamente y en cadenas grandes puede ser un proceso muy costoso.&lt;br /&gt;
otra forma es tener un cursor, de forma que evitamos tocar la cadena y únicamente extraemos la parte que nos interesa:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;function fread_str_cur(&amp;amp;$cur, &amp;amp;$str, $len) { $data = substr($str, $cur, $len); $cur += $len; return $data; }&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: inherit;"&gt;En PHP se puede generar un stream a partir de una cadena con relativa facilidad. Hay diversas formas:&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;$f = fopen('data://text/plain;base64,' . base64_encode($data), 'r+');&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;$f = fopen('php://memory', 'w+'); fwrite($f, $data); fseek($f, 0);&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="color: #0000bb;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;span class="Apple-style-span" style="color: #0000bb;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;
&lt;b&gt;&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;rtrim+\0&lt;/span&gt;&lt;/b&gt;&lt;br /&gt;
Al trabajar con archivos binarios, suele trabajarse con stringz muy amenudo o con cadenas que tienen un right padding de o bien espacios o bien el carácter 0.&lt;br /&gt;
La función rtrim nos puede ayudar a eliminar esos caracteres sobrantes de la cadena. rtrim tiene un segundo parámetro opcional que permite especificar los caracteres a eliminar. En nuestro caso \0. Por defecto elimina espacios, tabuladores, saltos de línea y el carácter \0. Pero en estos casos nos interesa únicamente que elimine el carácter de padding:&lt;br /&gt;
&lt;a href="http://es.php.net/rtrim"&gt;rtrim&lt;/a&gt;("hola\0\0\0", "\0") == 'hola'&lt;br /&gt;
&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-size: x-large;"&gt;&lt;b&gt;Algunas funciones de utilidad:&lt;/b&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace; font-size: small;"&gt;function fread1($f) { @list(, $r) = unpack('C', fread($f, 1)); return $r; }&lt;/span&gt;&lt;br /&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;// Little Endian.&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;function fread2le($f) { @list(, $r) = unpack('v', fread($f, 2)); return $r; }&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;function fread4le($f) { @list(, $r) = unpack('V', fread($f, 4)); return $r; }&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;function freadsz($f, $l) { return rtrim(fread($f, $l), "\0"); }&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;function hex &amp;nbsp;($str) { return strtoupper(($v = unpack('H*', $str)) ? $v[1] : ''); }&lt;br /&gt;
function unhex($str) { return pack('H*', $str); }&lt;br /&gt;
unhex(hex('prueba')) == 'prueba';&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;function fread_str(&amp;amp;$str, $len) { $data = substr($str, 0, $len); $str = substr($str, $len); return $data; }&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;br /&gt;
Variantes:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;function fread1($f) { return ord(fread($f, 1)); }&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;function fread2le($f) {&amp;nbsp;return ($v =&amp;nbsp;unpack('v', fread($f, 2))) ? $v[1] : false; }&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;function fread4le($f) {&amp;nbsp;return ($v =&amp;nbsp;unpack('V', fread($f, 4))) ? $v[1] : false; }&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;/div&gt;&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-style-span" style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;function freadsz($f, $l = false) {&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;if ($l === false) {&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;$s = '';&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;while (!feof($f)) {&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;   &lt;/span&gt;$c = fread($f, 1);&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;   &lt;/span&gt;if ($c == '' || $c == "\0") break;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;   &lt;/span&gt;$s .= $c;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;}&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;return $s;&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;} else {&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;  &lt;/span&gt;return rtrim(fread($f, $l), "\0");&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;&lt;span class="Apple-tab-span" style="white-space: pre;"&gt; &lt;/span&gt;}&lt;/div&gt;&lt;div style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"&gt;}&lt;/div&gt;&lt;/span&gt;&lt;br /&gt;
&lt;div&gt;&lt;br /&gt;
&lt;/div&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1250738086120444710-9168809400545835818?l=php.soywiz.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/NBx_kC31-VyFfxa59y-vICAz8sM/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/NBx_kC31-VyFfxa59y-vICAz8sM/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/NBx_kC31-VyFfxa59y-vICAz8sM/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/NBx_kC31-VyFfxa59y-vICAz8sM/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://php.soywiz.com/feeds/9168809400545835818/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://php.soywiz.com/2010/06/trabajando-con-archivos-binarios-en-php.html#comment-form" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1250738086120444710/posts/default/9168809400545835818?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1250738086120444710/posts/default/9168809400545835818?v=2" /><link rel="alternate" type="text/html" href="http://php.soywiz.com/2010/06/trabajando-con-archivos-binarios-en-php.html" title="Trabajando con archivos binarios en PHP" /><author><name>soywiz</name><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03708515771492521927" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;CUAGSXg8eSp7ImA9WxFWFEo.&quot;"><id>tag:blogger.com,1999:blog-1250738086120444710.post-5196813369020117664</id><published>2010-01-18T11:25:00.001+01:00</published><updated>2010-06-02T12:15:28.671+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-06-02T12:15:28.671+02:00</app:edited><title>Simulate static binding on PHP &lt; 5.3</title><content type="html">&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;class A {&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;const CONSTANT = 'A';&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;function __construct() {&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;  &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;echo constant(get_class($this) . '::CONSTANT');&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;  &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;// echo self::CONSTANT; // No static. Would output AA instead of AB.&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;  &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;// echo static::CONSTANT; // PHP &amp;gt;= 5.3&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;class B extends A {&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span class="Apple-tab-span" style="white-space: pre;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt; &lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;const CONSTANT = 'B';&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;ob_start();&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;$a = new A;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;$b = new B;&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;var_dump(ob_get_clean() == 'AB');&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;&lt;br /&gt;
&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;&lt;span class="Apple-style-span" style="font-size: small;"&gt;?&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1250738086120444710-5196813369020117664?l=php.soywiz.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Jrd4cO7Dvithi54CZhdQqFn8MGk/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Jrd4cO7Dvithi54CZhdQqFn8MGk/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Jrd4cO7Dvithi54CZhdQqFn8MGk/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Jrd4cO7Dvithi54CZhdQqFn8MGk/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://php.soywiz.com/feeds/5196813369020117664/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://php.soywiz.com/2010/01/simulate-static-binding-on-php-53.html#comment-form" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1250738086120444710/posts/default/5196813369020117664?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1250738086120444710/posts/default/5196813369020117664?v=2" /><link rel="alternate" type="text/html" href="http://php.soywiz.com/2010/01/simulate-static-binding-on-php-53.html" title="Simulate static binding on PHP &lt; 5.3" /><author><name>soywiz</name><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03708515771492521927" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;DkAMQHk6fSp7ImA9WxNVEEk.&quot;"><id>tag:blogger.com,1999:blog-1250738086120444710.post-1043052705792813799</id><published>2009-10-20T10:34:00.003+02:00</published><updated>2009-10-20T15:19:41.715+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-10-20T15:19:41.715+02:00</app:edited><title>Macro operaciones con las funciones array_*</title><content type="html">Quitar todos los espacios de principio y de final de cada elemento en un array (&lt;b&gt;array_map&lt;/b&gt;):&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;$array_trimmed = array_map('trim', $array);&lt;/span&gt;&lt;br /&gt;
Alternativas:&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;$array_trimmed = array();&amp;nbsp;foreach ($array as $v)&amp;nbsp;$array_trimmed[] = trim($v);&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;foreach ($array_trimmed as &amp;amp;$v)&amp;nbsp;$v = trim($v); // Mala idea. PHP tiene leaks desde hace mucho tiempo con foreach + &amp;amp;.&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Obtener una lista segura de enteros (por ejemplo IDs) para insertar en una query dentro de un IN().&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;$array_str_list = implode(',', array_map('intval', $array));&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Filtrar un array obteniendo únicamente valores numéricos (&lt;b&gt;array_filter&lt;/b&gt;):&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;$array_numbers = array_filter($array, 'is_numeric')&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Para creación de valores para un insert con pdo (&lt;b&gt;array_map&lt;/b&gt;):&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;$query_insert_values = implode(",", array_map(array($pdo, 'quote'), $values))&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Para creación de asignaciones en un update con pdo&amp;nbsp;(&lt;b&gt;array_map&lt;/b&gt; con dos arrays):&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;$query_set =&amp;nbsp;implode(',', array_map(function($k, $v) use ($pdo) {&lt;/span&gt;&lt;br /&gt;
&lt;span style="white-space: pre;"&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;   &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;return '`' . implode('`,`', explode('.', $k)) . '`=' . $pdo-&amp;gt;quote($v);&lt;/span&gt;&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;}, array_keys($array), array_values($array)));&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
Obtener una lista de elementos únicos usando un array que contiene un número indeterminado de arrays (&lt;b&gt;array_reduce&lt;/b&gt;):&lt;br /&gt;
&lt;br /&gt;
&lt;span style="font-family: 'Courier New', Courier, monospace;"&gt;$array_unique = array_unique( array_reduce( $arrays, 'array_merge', array() ) );&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1250738086120444710-1043052705792813799?l=php.soywiz.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/lByzE40gETqM9RC9-Lugze7QQoc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/lByzE40gETqM9RC9-Lugze7QQoc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/lByzE40gETqM9RC9-Lugze7QQoc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/lByzE40gETqM9RC9-Lugze7QQoc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://php.soywiz.com/feeds/1043052705792813799/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://php.soywiz.com/2009/10/macro-operaciones-con-las-funciones.html#comment-form" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1250738086120444710/posts/default/1043052705792813799?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1250738086120444710/posts/default/1043052705792813799?v=2" /><link rel="alternate" type="text/html" href="http://php.soywiz.com/2009/10/macro-operaciones-con-las-funciones.html" title="Macro operaciones con las funciones array_*" /><author><name>soywiz</name><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03708515771492521927" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;D04CRXgycSp7ImA9WxJbEEw.&quot;"><id>tag:blogger.com,1999:blog-1250738086120444710.post-1103392193092168308</id><published>2009-07-19T17:06:00.000+02:00</published><updated>2009-07-19T17:06:04.699+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-19T17:06:04.699+02:00</app:edited><title>Crear "estructuras" en php5.3</title><content type="html">En alguna ocasión me ha interesado crear una clase que contendría simplemente unos cuantos atributos y poco más y al final he acabado haciendo un constructor del tipo:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;class mystruct { &lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; public $a, $b, $c;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; function __construct($a, $b, $c) {&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; $this-&amp;gt;a = $a;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; $this-&amp;gt;b = $b;&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; $this-&amp;gt;c = $c; &lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/div&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;}&lt;/span&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;class struct {&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;static public function create() {&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;$obj = new static;&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;$keys = array_keys((array)$obj);&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;foreach (func_get_args() as $k =&amp;gt; $v) $obj-&amp;gt;{$keys[$k]} = $v;&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;return $obj;&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br /&gt;
}&lt;/div&gt;&lt;br /&gt;
Para versiones anteriores de php podemos usar el constructor:&lt;br /&gt;
&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;class struct {&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;static function __construct() {&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; $keys = array_keys((array)$obj);&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;foreach (func_get_args() as $k =&amp;gt; $v) $this-&amp;gt;{$keys[$k]} = $v;&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;return $this;&lt;br /&gt;
&amp;nbsp;&amp;nbsp; &amp;nbsp;}&lt;br /&gt;
}&lt;/div&gt;&lt;br /&gt;
&lt;br /&gt;
Con lo que podríamos hacer lo siguiente:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;class mystruct extends struct { public $a, $b, $c; }&lt;/div&gt;&lt;div style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;mystruct::create(1, 2, 3);&lt;/div&gt;o&lt;br /&gt;
&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;new mystruct(1, 2, 3);&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1250738086120444710-1103392193092168308?l=php.soywiz.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/3r057J_sGLa1mLkXbWPfwNvlXcU/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/3r057J_sGLa1mLkXbWPfwNvlXcU/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/3r057J_sGLa1mLkXbWPfwNvlXcU/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/3r057J_sGLa1mLkXbWPfwNvlXcU/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://php.soywiz.com/feeds/1103392193092168308/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://php.soywiz.com/2009/07/crear-estructuras-en-php53.html#comment-form" title="2 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1250738086120444710/posts/default/1103392193092168308?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1250738086120444710/posts/default/1103392193092168308?v=2" /><link rel="alternate" type="text/html" href="http://php.soywiz.com/2009/07/crear-estructuras-en-php53.html" title="Crear &quot;estructuras&quot; en php5.3" /><author><name>soywiz</name><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03708515771492521927" /></author><thr:total>2</thr:total></entry><entry gd:etag="W/&quot;Ak4NQH88eSp7ImA9WxJUF0U.&quot;"><id>tag:blogger.com,1999:blog-1250738086120444710.post-2577656773291717083</id><published>2009-07-17T01:57:00.005+02:00</published><updated>2009-07-17T02:03:11.171+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-17T02:03:11.171+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="proyectos" /><category scheme="http://www.blogger.com/atom/ns#" term="phpste" /><category scheme="http://www.blogger.com/atom/ns#" term="php5.3" /><title>Novedades con phpSTE</title><content type="html">Ahora que vuelvo a tener Internet en plan bien, y ya vuelvo a estar con mis proyectos, he seguido mejorando phpSTE.&lt;br /&gt;&lt;br /&gt;He cambiado bastantes cosas desde que lo empecé, y cambiaré bastantes más posiblemente hasta que esté pulido del todo.&lt;br /&gt;&lt;br /&gt;Por ahora ocupa unas 550 líneas y ya es bastante funcional.&lt;br /&gt;&lt;br /&gt;Además de soportar herencia, he añadido los siguientes tags:&lt;br /&gt;&lt;br /&gt;&lt;div  style=";font-family:&amp;quot;;"&gt;&lt;span style="font-size:85%;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;div  style=";font-family:&amp;quot;;"&gt;&lt;span style="font-size:85%;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;{extends name=""} - extiende un template.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;{include name=""} - incluye un template.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;{block name=""}{/block} - define e imprime/modifica un bloque.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;{addblock name=""}{/addblock} - modifica un bloque añadiendo el contenido al final.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;{blockdef name=""}{/blockdef} - define un bloque sin utilizarlo.&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;{putblock name=""} - imprime un bloque existente.&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;{t}{/t} - llama a la función de gettext&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;{if cond=""}{/if}&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;{elseif cond=""}{else}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;{for var="" from="" to="" step=""}{/for}&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;{foreach list="" var=""}{/foreach}&lt;/span&gt;&lt;/span&gt; &lt;div  style=";font-family:&amp;quot;;"&gt;&lt;span style="font-size:85%;"&gt;&lt;/span&gt;&lt;/div&gt;&lt;br /&gt;&lt;br /&gt;He hecho optimizaciones para que los tags puedan saber si el contenido es un literal, de forma que {t}Texto{/t} se convertiría a  mientras que {t}{if cond=1}Texto{/if}{/t} se convertiría a Texto&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1250738086120444710-2577656773291717083?l=php.soywiz.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/ONeNvglOExyrcg-me8My1a9zusY/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ONeNvglOExyrcg-me8My1a9zusY/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/ONeNvglOExyrcg-me8My1a9zusY/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/ONeNvglOExyrcg-me8My1a9zusY/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://php.soywiz.com/feeds/2577656773291717083/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://php.soywiz.com/2009/07/novedades-con-phpste.html#comment-form" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1250738086120444710/posts/default/2577656773291717083?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1250738086120444710/posts/default/2577656773291717083?v=2" /><link rel="alternate" type="text/html" href="http://php.soywiz.com/2009/07/novedades-con-phpste.html" title="Novedades con phpSTE" /><author><name>soywiz</name><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03708515771492521927" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;CU8AQHo6fCp7ImA9WxJVGE4.&quot;"><id>tag:blogger.com,1999:blog-1250738086120444710.post-6611506241033798009</id><published>2009-07-06T00:41:00.001+02:00</published><updated>2009-07-06T00:44:01.414+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-07-06T00:44:01.414+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="proyectos" /><category scheme="http://www.blogger.com/atom/ns#" term="phpste" /><category scheme="http://www.blogger.com/atom/ns#" term="php5.3" /><title>phpSTE</title><content type="html">&lt;p&gt;phpSTE (PHP Simple Template Engine) es un sistema de templates que he empezado a hacer hoy.&lt;/p&gt;  &lt;p&gt;Se caracteriza por ser liviano, rápido y sencillo. Actualmente no es 100% funcional, ni lo he testeado lo suficiente, pero ya empieza a hacer cosas.&lt;/p&gt;  &lt;p&gt;Además, soporta herencia de templates.&lt;/p&gt;  &lt;p&gt;Está programado para PHP5.3 o superior. Hace uso de namespaces, late static binding y alguna otra cosa de esta versión.&lt;/p&gt;  &lt;p&gt;&lt;a title="http://code.google.com/p/phpste/" href="http://code.google.com/p/phpste/"&gt;http://code.google.com/p/phpste/&lt;/a&gt;&lt;/p&gt;  &lt;p&gt;La idea es que el engine terminado no supere las 1000 líneas de código comentado y que esté todo en un único archivo para facilitar al máximo su inclusión en otros proyectos.&lt;/p&gt;  &lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1250738086120444710-6611506241033798009?l=php.soywiz.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/4zrA3aoJkSvD9Q75SVzMPJbQ-Yc/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/4zrA3aoJkSvD9Q75SVzMPJbQ-Yc/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/4zrA3aoJkSvD9Q75SVzMPJbQ-Yc/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/4zrA3aoJkSvD9Q75SVzMPJbQ-Yc/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://php.soywiz.com/feeds/6611506241033798009/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://php.soywiz.com/2009/07/phpste.html#comment-form" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1250738086120444710/posts/default/6611506241033798009?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1250738086120444710/posts/default/6611506241033798009?v=2" /><link rel="alternate" type="text/html" href="http://php.soywiz.com/2009/07/phpste.html" title="phpSTE" /><author><name>soywiz</name><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03708515771492521927" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;CEcAQ3k_fyp7ImA9WxFWFEU.&quot;"><id>tag:blogger.com,1999:blog-1250738086120444710.post-7009366331622186981</id><published>2009-06-05T16:20:00.002+02:00</published><updated>2010-06-02T14:34:02.747+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2010-06-02T14:34:02.747+02:00</app:edited><title>Calculando el número de apariciones de un color en una imagen paletizada usando GD.</title><content type="html">&lt;span class="Apple-style-span" style="font-family: Consolas; font-size: 13px; white-space: pre;"&gt;$i = imagecreate(1000, 1000);&lt;/span&gt;&lt;br /&gt;
&lt;pre class="defaultcode" style="background-attachment: initial; background-clip: initial; background-color: white; background-image: initial; background-origin: initial; background-position: initial initial; background-repeat: initial initial; color: black; font: normal normal normal 10pt/normal Consolas;"&gt;$c1 = imagecolorallocate($i, 0x00, 0x00, 0x00);
 $c2 = imagecolorallocate($i, 0xFF, 0xFF, 0xFF);
 
 imagefill($i, 0, 0, $c2);
 
 for ($n = 0; $n &amp;lt; 100; $n++) imagesetpixel($i, $n, $n, $c1);

 printf("Method1 (iterating using php) {\n");
 {
  $t0 = microtime(true);
  ob_start(); imagegd($i); $data = substr(ob_get_clean(), 0x40D);
  printf("  Output image: %.4f seconds\n", microtime(true) - $t0);

  $t0 = microtime(true);
  $count = array();
  list($w, $h) = array(imageSX($i), imageSY($i));
  for ($y = 0; $y &amp;lt; $h; $y++) {
   for ($x = 0; $x &amp;lt; $w; $x++) {
    @$count[imagecolorat($i, $x, $y)]++;
   }
  }
  $count = count_chars($data, 1);
  arsort($count);
  printf("  Counting: %.4f seconds\n", microtime(true) - $t0);
  print_r($count);
 }
 printf("}\n");
 
 printf("Method2 (hack) {\n");
 {
  $t0 = microtime(true);
  ob_start(); imagegd($i); $data = substr(ob_get_clean(), 0x40D);
  printf("  Output image: %.4f seconds\n", microtime(true) - $t0);

  $t0 = microtime(true);
  $count = count_chars($data, 1);
  arsort($count);
  printf("  Counting: %.4f seconds\n", microtime(true) - $t0);
  print_r($count);
 }
 printf("}\n");&lt;/pre&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1250738086120444710-7009366331622186981?l=php.soywiz.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/nWHlYNZFxVvEQ5-yxCm4TfF4slU/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/nWHlYNZFxVvEQ5-yxCm4TfF4slU/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/nWHlYNZFxVvEQ5-yxCm4TfF4slU/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/nWHlYNZFxVvEQ5-yxCm4TfF4slU/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://php.soywiz.com/feeds/7009366331622186981/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://php.soywiz.com/2009/06/calculando-el-numero-de-apariciones-de.html#comment-form" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1250738086120444710/posts/default/7009366331622186981?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1250738086120444710/posts/default/7009366331622186981?v=2" /><link rel="alternate" type="text/html" href="http://php.soywiz.com/2009/06/calculando-el-numero-de-apariciones-de.html" title="Calculando el número de apariciones de un color en una imagen paletizada usando GD." /><author><name>soywiz</name><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03708515771492521927" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;CUYHQHo9eip7ImA9WxJRGE8.&quot;"><id>tag:blogger.com,1999:blog-1250738086120444710.post-2483376984662039594</id><published>2009-05-20T14:38:00.000+02:00</published><updated>2009-05-20T14:38:51.462+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-20T14:38:51.462+02:00</app:edited><title>El último día de un mes en php5</title><content type="html">Mes anterior:&lt;br /&gt;
date_create(date('Ym01'))-&gt;modify('-1 day')&lt;br /&gt;
&lt;br /&gt;
Este mes:&lt;br /&gt;
date_create(date('Ym01'))-&gt;modify('+1 month -1 day')&lt;br /&gt;
&lt;br /&gt;
Un mes concreto mediante timestamp:&lt;br /&gt;
date_create(date('Ym01', $timestamp))-&gt;modify('+1 month -1 day')&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1250738086120444710-2483376984662039594?l=php.soywiz.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/rgdLEBfdwBYywUXkfOwkgfjtoJw/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/rgdLEBfdwBYywUXkfOwkgfjtoJw/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/rgdLEBfdwBYywUXkfOwkgfjtoJw/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/rgdLEBfdwBYywUXkfOwkgfjtoJw/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://php.soywiz.com/feeds/2483376984662039594/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://php.soywiz.com/2009/05/el-ultimo-dia-de-un-mes-en-php5.html#comment-form" title="1 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1250738086120444710/posts/default/2483376984662039594?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1250738086120444710/posts/default/2483376984662039594?v=2" /><link rel="alternate" type="text/html" href="http://php.soywiz.com/2009/05/el-ultimo-dia-de-un-mes-en-php5.html" title="El último día de un mes en php5" /><author><name>soywiz</name><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03708515771492521927" /></author><thr:total>1</thr:total></entry><entry gd:etag="W/&quot;D04FR3w9fyp7ImA9WxJSFU0.&quot;"><id>tag:blogger.com,1999:blog-1250738086120444710.post-150546062313360181</id><published>2009-05-05T08:45:00.000+02:00</published><updated>2009-05-05T08:45:16.267+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-05-05T08:45:16.267+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="phpmedia" /><category scheme="http://www.blogger.com/atom/ns#" term="php5.3" /><title>Ejemplo de RPG 2D en phpmedia</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;Aprovechando que hacía tiempo hice una prueba de minirpg en javascript, y luego un port en flash online y con chat (cliente+servidor en D) y que ya tenía los gráficos y las animaciones, he portado eso mismo a php usando phpmedia.&lt;/div&gt;Los gráficos son de Tales of Eternia &lt;a href="http://toe.tales-tra.com/" target="_blank"&gt;(juego que traducimos al español hace unos años)&lt;/a&gt;. Con un filtro 2xsai o 2xeagle si no recuerdo mal. Los personajes que se usan en la demo son Reid y Farah. Mientras que el escenario (que todavía no está puesto ya que es solo una demo de colisiones), es el Dojo de Regulus.&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://phpelegante.googlepages.com/sample_rpg.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="327" src="http://phpelegante.googlepages.com/sample_rpg.png" width="420" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&amp;nbsp;&lt;a href="http://phpelegante.googlepages.com/phpmedia_rpg_test_eternia.7z"&gt;Prueba de RPG 2D en phpmedia&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1250738086120444710-150546062313360181?l=php.soywiz.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/tA2aJWzTfd3C26Vis49jF2CwMm0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/tA2aJWzTfd3C26Vis49jF2CwMm0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/tA2aJWzTfd3C26Vis49jF2CwMm0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/tA2aJWzTfd3C26Vis49jF2CwMm0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://php.soywiz.com/feeds/150546062313360181/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://php.soywiz.com/2009/05/ejemplo-de-rpg-2d-en-phpmedia.html#comment-form" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1250738086120444710/posts/default/150546062313360181?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1250738086120444710/posts/default/150546062313360181?v=2" /><link rel="alternate" type="text/html" href="http://php.soywiz.com/2009/05/ejemplo-de-rpg-2d-en-phpmedia.html" title="Ejemplo de RPG 2D en phpmedia" /><author><name>soywiz</name><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03708515771492521927" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;Ck4BQ3k-cCp7ImA9WxJTFk4.&quot;"><id>tag:blogger.com,1999:blog-1250738086120444710.post-2604983775768942660</id><published>2009-04-25T05:01:00.003+02:00</published><updated>2009-04-25T05:42:32.758+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-25T05:42:32.758+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="phpmedia" /><category scheme="http://www.blogger.com/atom/ns#" term="php5.3" /><title>Y llegaron los shaders...</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://phpelegante.googlepages.com/file.jpg" imageanchor="1"&gt;&lt;img src="http://phpelegante.googlepages.com/file.jpg" border="0" height="150" width="200" /&gt;&lt;/a&gt;&lt;a href="http://phpelegante.googlepages.com/mask.png" imageanchor="1"&gt;&lt;img src="http://phpelegante.googlepages.com/mask.png" border="0" height="150" width="200" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;&lt;div style="text-align: center;"&gt;&lt;a href="http://phpelegante.googlepages.com/shaders.jpg" imageanchor="1"&gt;&lt;img src="http://phpelegante.googlepages.com/shaders.jpg" border="0" height="325" width="420" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://phpelegante.googlepages.com/shaders2.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img src="http://phpelegante.googlepages.com/shaders2.jpg" border="0" height="325" width="420" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div style="text-align: center;"&gt;&lt;/div&gt;&lt;br /&gt;Ya se puede usar &lt;a href="http://en.wikipedia.org/wiki/GLSL"&gt;GLSL &lt;/a&gt;en phpmedia:&lt;br /&gt;&lt;br /&gt;Ejemplo: &lt;a href="http://phpelegante.googlepages.com/phpmedia_test_glsl.7z"&gt;http://phpelegante.googlepages.com/phpmedia_test_glsl.7z&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-size:x-small;"&gt;&lt;br /&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family: courier new;"&gt;error_reporting(E_ALL | E_STRICT);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;Screen::title('Shader test');&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;$screen = Screen::init(800, 600);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;$key = 'Keyboard';&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;$shader = new Shader("&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-family: courier new;font-size:85%;color:red;"  &gt;    uniform sampler2D image, mask;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family: courier new;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: courier new;font-size:85%;color:red;"  &gt;&lt;br /&gt;    uniform float step;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family: courier new;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: courier new;font-size:85%;color:red;"  &gt;&lt;br /&gt;    void main (void) {&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family: courier new;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: courier new;font-size:85%;color:red;"  &gt;&lt;br /&gt;        gl_FragColor.rgb = texture2D(image, vec2(gl_TexCoord[0])).rgb;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family: courier new;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: courier new;font-size:85%;color:red;"  &gt;&lt;br /&gt;        gl_FragColor.a   = texture2D(mask , vec2(gl_TexCoord[1])).r + step;&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family: courier new;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: courier new;font-size:85%;color:red;"  &gt;&lt;br /&gt;    }&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;");&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;$mask   = Bitmap::fromFile('mask.png');&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;$image  = Bitmap::fromFile('file.jpg');&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;$arrows = Bitmap::fromFile('arrows.png');&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;$v = -1.0;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;$timer = 0;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;while (!$key::pressed($key::ESC)) {&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;    if ($key::down($key::LEFT)) $v -= 0.03;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;    if ($key::down($key::RIGHT)) $v += 0.03;&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;    Math::clamp($v, -1.0, 1.0);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;    $screen-&gt;blit($image, 0, 0, 1, 0, 1, &lt;/span&gt;&lt;/span&gt;&lt;span style="font-family: courier new;font-size:85%;color:red;"  &gt;$shader&lt;/span&gt;&lt;span style="font-family: courier new;font-size:85%;color:red;"  &gt;,&lt;/span&gt;&lt;span style="font-family: courier new;font-size:85%;color:red;"  &gt; &lt;/span&gt;&lt;span style="font-family: courier new;font-size:85%;color:red;"  &gt;array&lt;/span&gt;&lt;span style="font-family: courier new;font-size:85%;color:red;"  &gt;(&lt;/span&gt;&lt;span style="font-family: courier new;font-size:85%;color:red;"  &gt;'mask'&lt;/span&gt;&lt;span style="font-family: courier new;font-size:85%;color:red;"  &gt; &lt;/span&gt;&lt;span style="font-family: courier new;font-size:85%;color:red;"  &gt;=&gt;&lt;/span&gt;&lt;span style="font-family: courier new;font-size:85%;color:red;"  &gt; &lt;/span&gt;&lt;span style="font-family: courier new;font-size:85%;color:red;"  &gt;$mask&lt;/span&gt;&lt;span style="font-family: courier new;font-size:85%;color:red;"  &gt;,&lt;/span&gt;&lt;span style="font-family: courier new;font-size:85%;color:red;"  &gt; &lt;/span&gt;&lt;span style="font-family: courier new;font-size:85%;color:red;"  &gt;'step'&lt;/span&gt;&lt;span style="font-family: courier new;font-size:85%;color:red;"  &gt; &lt;/span&gt;&lt;span style="font-family: courier new;font-size:85%;color:red;"  &gt;=&gt;&lt;/span&gt;&lt;span style="font-family: courier new;font-size:85%;color:red;"  &gt; &lt;/span&gt;&lt;span style="font-family: courier new;font-size:85%;color:red;"  &gt;$v&lt;/span&gt;&lt;span style="font-family: courier new;font-size:85%;color:red;"  &gt;)&lt;/span&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family: courier new;"&gt;);&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;    $screen-&gt;blit($arrows, 16, 16, 1, 0, 0.6 + abs(cos($timer / 64)) * 0.8);&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;    $timer++;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;    Screen::frame();&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family: courier new;"&gt;}&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1250738086120444710-2604983775768942660?l=php.soywiz.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/GEQ_3ZBGbI471X6njzLRAocWTM0/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/GEQ_3ZBGbI471X6njzLRAocWTM0/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/GEQ_3ZBGbI471X6njzLRAocWTM0/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/GEQ_3ZBGbI471X6njzLRAocWTM0/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://php.soywiz.com/feeds/2604983775768942660/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://php.soywiz.com/2009/04/y-llegaron-los-shaders.html#comment-form" title="1 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1250738086120444710/posts/default/2604983775768942660?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1250738086120444710/posts/default/2604983775768942660?v=2" /><link rel="alternate" type="text/html" href="http://php.soywiz.com/2009/04/y-llegaron-los-shaders.html" title="Y llegaron los shaders..." /><author><name>soywiz</name><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03708515771492521927" /></author><thr:total>1</thr:total></entry><entry gd:etag="W/&quot;DUAMRHY8fSp7ImA9WxJTFUg.&quot;"><id>tag:blogger.com,1999:blog-1250738086120444710.post-1690862034131053146</id><published>2009-04-24T09:21:00.001+02:00</published><updated>2009-04-24T09:23:05.875+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-24T09:23:05.875+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="phpmedia" /><category scheme="http://www.blogger.com/atom/ns#" term="php5.3" /><title>Ejemplo de nave (mejorado)</title><content type="html">&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://phpelegante.googlepages.com/nave_shoot_sshot.jpg" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="327" src="http://phpelegante.googlepages.com/nave_shoot_sshot.jpg" width="420" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;br /&gt;
&lt;a href="http://phpelegante.googlepages.com/nave_shoot.7z"&gt;http://phpelegante.googlepages.com/nave_shoot.7z&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1250738086120444710-1690862034131053146?l=php.soywiz.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/vkRI79l6wYMq0LAiJx9TMV2Xm7g/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/vkRI79l6wYMq0LAiJx9TMV2Xm7g/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/vkRI79l6wYMq0LAiJx9TMV2Xm7g/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/vkRI79l6wYMq0LAiJx9TMV2Xm7g/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://php.soywiz.com/feeds/1690862034131053146/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://php.soywiz.com/2009/04/ejemplo-de-nave-mejorado.html#comment-form" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1250738086120444710/posts/default/1690862034131053146?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1250738086120444710/posts/default/1690862034131053146?v=2" /><link rel="alternate" type="text/html" href="http://php.soywiz.com/2009/04/ejemplo-de-nave-mejorado.html" title="Ejemplo de nave (mejorado)" /><author><name>soywiz</name><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03708515771492521927" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;DUAHQHw9fyp7ImA9WxJTFUg.&quot;"><id>tag:blogger.com,1999:blog-1250738086120444710.post-2688125067032714680</id><published>2009-04-21T08:13:00.003+02:00</published><updated>2009-04-24T09:22:11.267+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-24T09:22:11.267+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="phpmedia" /><category scheme="http://www.blogger.com/atom/ns#" term="php5.3" /><title>Ejemplo de nave</title><content type="html">He hecho un pequeño ejemplo en phpmedia 2: &lt;br /&gt;
&lt;br /&gt;
&lt;a href="http://code.google.com/p/phpmedia/wiki/SampleNave"&gt;http://code.google.com/p/phpmedia/wiki/SampleNave&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;/div&gt;&lt;div class="separator" style="clear: both; text-align: center;"&gt;&lt;a href="http://phpelegante.googlepages.com/nave_sample.png" imageanchor="1" style="margin-left: 1em; margin-right: 1em;"&gt;&lt;img border="0" height="329" src="http://phpelegante.googlepages.com/nave_sample.png" width="420" /&gt;&lt;/a&gt;&lt;/div&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1250738086120444710-2688125067032714680?l=php.soywiz.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/tjbteJNtma5dt6PCuvQbISP1GhI/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/tjbteJNtma5dt6PCuvQbISP1GhI/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/tjbteJNtma5dt6PCuvQbISP1GhI/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/tjbteJNtma5dt6PCuvQbISP1GhI/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://php.soywiz.com/feeds/2688125067032714680/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://php.soywiz.com/2009/04/ejemplo-de-nave.html#comment-form" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1250738086120444710/posts/default/2688125067032714680?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1250738086120444710/posts/default/2688125067032714680?v=2" /><link rel="alternate" type="text/html" href="http://php.soywiz.com/2009/04/ejemplo-de-nave.html" title="Ejemplo de nave" /><author><name>soywiz</name><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03708515771492521927" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;DUQCRXk9cCp7ImA9WxJTFUg.&quot;"><id>tag:blogger.com,1999:blog-1250738086120444710.post-9031500726003795403</id><published>2009-04-20T05:13:00.011+02:00</published><updated>2009-04-24T09:16:04.768+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-24T09:16:04.768+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="extensiones" /><category scheme="http://www.blogger.com/atom/ns#" term="phpmedia" /><category scheme="http://www.blogger.com/atom/ns#" term="php5" /><category scheme="http://www.blogger.com/atom/ns#" term="php5.3" /><title>phpMedia 2.0</title><content type="html">&lt;center&gt;&lt;br /&gt;
&lt;img border="0" src="http://phpmedia.googlecode.com/svn/www/logo.png" /&gt;&lt;/center&gt;&lt;br /&gt;
&lt;br /&gt;
Hace unos 5 años, hice una extensión para php que permitía hacer aplicaciones multimedia 2D. Por aquel entonces usaba PHP4 y Allegro. Todo el tema gráfico se hacía por software y no permitía conseguir un buen rendimiento. El API no era orientado a objetos y PHP4&amp;nbsp; estaba mucho más limitado que en la actualidad. El proyecto se alojaba en sourceforge &lt;a href="http://phpmedia.sourceforge.net/"&gt;aquí&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
Hace un par de semanas, decidí que estaría bien revivir aquello, pero hacerlo mucho mejor: con una interfaz orientada a objetos para PHP5.3 y usando OpenGL con aceleración completa por hardware.&lt;br /&gt;
&lt;br /&gt;
Establecí un proyecto en googlecode. Y me puse a idear el API que tendría. El objetivo es conseguir un API sencillo y útil. Que no sea totalmente versatil, pero que deje hacer bastantes cosas.&lt;br /&gt;
Hice un prototipo de interfaz en PHP, y un generador de documentación para googlecode.&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;&lt;a href="http://phpmedia.googlecode.com/svn/trunk/api.php"&gt;http://phpmedia.googlecode.com/svn/trunk/api.php&lt;/a&gt;&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;&lt;a href="http://code.google.com/p/phpmedia/wiki/API"&gt;http://code.google.com/p/phpmedia/wiki/API&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;Aunque no hice nada, ya tenía mas o menos pensada parte del API.&lt;br /&gt;
Esta tarde/noche, me he puesto con ello. Con unos resultados muy prometedores. He tenido muy pocos problemas y ha ido todo como esperaba o incluso mejor.&lt;br /&gt;
&lt;br /&gt;
Como resultado he sacado una primera versión usable, para PHP5.3. En la página del proyecto está.&lt;br /&gt;
&lt;br /&gt;
Lo que he hecho:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Soporte básico de teclado. Las teclas principales. Detectar pulsaciones o detectar si está pulsada o levantada la tecla.&lt;/li&gt;
&lt;li&gt;Inicialización gráfica (ventana o pantalla completa)&lt;/li&gt;
&lt;li&gt;Clase Bitmap (bastante avanzada). Permite crear nuevos bitmaps, cargar desde archivos o desde cadenas. Permite hacer recortes, clonar réplicas.&lt;br /&gt;
&lt;/li&gt;
&lt;/ul&gt;Lo que falta:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Mejorar el soporte de teclado.&lt;/li&gt;
&lt;li&gt;Soporte para ratón.&lt;/li&gt;
&lt;li&gt;Soporte para gamepad.&lt;/li&gt;
&lt;li&gt;Todo el tema del audio.&lt;/li&gt;
&lt;li&gt;Shaders.&lt;br /&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;br /&gt;
Ejemplo de prueba + archivos necesarios:&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;&lt;/ul&gt;&lt;ul&gt;&lt;li&gt;&lt;a href="http://phpelegante.googlepages.com/test_phpmedia_20.7z"&gt;http://phpelegante.googlepages.com/test_phpmedia_20.7z&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://phpmedia.googlecode.com/files/php_media2.0-alpha%2Bphp53_min.7z"&gt;http://phpmedia.googlecode.com/files/php_media2.0-alpha%2Bphp53_min.7z&lt;/a&gt; &lt;a href="http://phpmedia.googlecode.com/files/phpmedia_dependences.7z"&gt;http://phpmedia.googlecode.com/files/phpmedia_dependences.7z&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;&lt;ul&gt;&lt;/ul&gt;Para probar el ejemplo, bajar todos los archivos. Y ejecutar el archivo test.bat. Teclas del cursor para desplazar la imagen. W/S para acercar/alejar la imagen. A/D para rotar la imagen. ESC para salir del ejemplo.&lt;br /&gt;
&lt;br /&gt;
Página del proyecto:&lt;a href="http://code.google.com/p/phpmedia/"&gt; http://code.google.com/p/phpmedia/&lt;/a&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1250738086120444710-9031500726003795403?l=php.soywiz.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Sf-IBGI1vFn0lLsIX409h4Rn7v8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Sf-IBGI1vFn0lLsIX409h4Rn7v8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Sf-IBGI1vFn0lLsIX409h4Rn7v8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Sf-IBGI1vFn0lLsIX409h4Rn7v8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://php.soywiz.com/feeds/9031500726003795403/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://php.soywiz.com/2009/04/phpmedia-20.html#comment-form" title="3 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1250738086120444710/posts/default/9031500726003795403?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1250738086120444710/posts/default/9031500726003795403?v=2" /><link rel="alternate" type="text/html" href="http://php.soywiz.com/2009/04/phpmedia-20.html" title="phpMedia 2.0" /><author><name>soywiz</name><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03708515771492521927" /></author><thr:total>3</thr:total><georss:point>41.387917 2.1699187</georss:point></entry><entry gd:etag="W/&quot;CkcNSHY4eSp7ImA9WxVaGUQ.&quot;"><id>tag:blogger.com,1999:blog-1250738086120444710.post-2104404096498986846</id><published>2009-04-17T19:39:00.004+02:00</published><updated>2009-04-17T19:41:39.831+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2009-04-17T19:41:39.831+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="performance" /><category scheme="http://www.blogger.com/atom/ns#" term="php5" /><title>¿serialize o json_encode?</title><content type="html">A partir de PHP 5.2, existen dos nuevas funciones llamadas &lt;a href="http://php.net/json_encode"&gt;json_encode&lt;/a&gt; y &lt;a href="http://php.net/json_decode"&gt;json_decode&lt;/a&gt; que permiten serializar variables con contenidos variables en php. La implementación está hecha en C, así que su rendimiento es bastante conveniente.&lt;br /&gt;
&lt;br /&gt;
JSON (JavaScript Object Notation) es un formato de intercambio de datos. Y tiene la peculiaridad de que la cadena generada es siempre una expresión válida en javascript. Además la cadena resultante es muy compacta, y se puede modificar con facilidad. En la actualidad ya es un formato ampliamente usado y soportado de manera oficial en muchos lenguajes de programación.&lt;br /&gt;
&lt;br /&gt;
La forma más eficiente y cómoda que había hasta la fecha para serializar variables, era la opción: &lt;a href="http://php.net/serialize"&gt;serialize&lt;/a&gt;/&lt;a href="http://php.net/unserialize"&gt;unserialize&lt;/a&gt;.&lt;br /&gt;
&lt;br /&gt;
A partir de PHP 5.2, con la nueva alternativa de json_*, está la duda: ¿siendo más compatible con otros lenguajes y además compacta y flexible, podría sustituir a la original?&lt;br /&gt;
&lt;br /&gt;
La respuesta es: no siempre.&lt;br /&gt;
&lt;br /&gt;
json_decode puede ser mucho más lento que unserialize en muchos casos.&lt;br /&gt;
Mientras que serialize almacena las longitudes de las cadenas, json_encode tiene que recorrerlas para conocer su longitud. Además la entrada de json_encode tiene que ser utf-8 y el parseo es bastante más lento.&lt;br /&gt;
&lt;br /&gt;
He hecho un pequeño programa para probar el rendimiento. El tamaño de la cadena generada por json siempre es más pequeño. El json se codifica mas rápido para arrays y números. Pero para cadenas, el rendimiento empeora mucho.&lt;br /&gt;
&lt;br /&gt;
&lt;blockquote&gt;&lt;span style="font-size: xx-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; function &amp;amp; generate_random_var( $maxdepth = 5, $base = 10, $strlen = 999 ) {&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; $r = array();&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; for ($n = 0, $l = mt_rand($base / 2, $base); $n &amp;lt; $l; $n++) {&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; switch (mt_rand(0, 4)) {&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; case 0: $r[] = mt_rand(); break;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; case 1: $r[] = str_repeat( '*', $strlen ); break;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; case 2: $r[] = false; break;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; case 3: $r[] = (object)array(1 =&amp;gt; 2); break;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; case 4: if ( $maxdepth &amp;gt; 0 ) $r[] = generate_random_var( mt_rand( 0, $maxdepth - 1), $base, $strlen ); break;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; return $r;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; mt_srand( 0 );&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; foreach (array(&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; array(4, 30, 9),&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; array(10, 30, 1),&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; array(0, 8000, 1),&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; array(0, 8000, 99),&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; array(0, 8000, 999),&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; array(4, 30, 99),&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; array(4, 30, 999),&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; ) as $config) {&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; list($maxdepth, $base, $strlen) = $config;&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; printf("config(depth=%d, elements=%d, strlen=%d):\n", $maxdepth, $base, $strlen);&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; $v = generate_random_var($maxdepth, $base, $strlen);&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; $t = microtime(true);&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; for ($n = 0; $n &amp;lt; 60; $n++) {&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; $s = &amp;amp; serialize($v);&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; unserialize($s);&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; printf("&amp;nbsp; serialize : time(%.3f), length(%d)\n", $t_serialize = microtime(true) - $t, $l_serialize = strlen($s));&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; $t = microtime(true);&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; for ($n = 0; $n &amp;lt; 60; $n++) {&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; $s = &amp;amp; json_encode($v);&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; json_decode($s);&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; printf("&amp;nbsp; json&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : time(%.3f), length(%d)\n", $t_json = microtime(true) - $t, $l_json = strlen($s));&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; &lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; printf("&amp;nbsp; diff: time(%d%%) | strlen(%d%%)\n", $t_json * 100 / $t_serialize, $l_json * 100 / $l_serialize);&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; &amp;nbsp;&amp;nbsp;&amp;nbsp; printf("\n");&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp; }&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;?&amp;gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;Resultados:&lt;br /&gt;
&lt;blockquote&gt;&lt;span style="font-size: x-small;"&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;config(depth=4, elements=30, strlen=9):&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; serialize : time(0.236), length(42431)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; json&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : time(0.171), length(19639)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; diff: time(72%) | strlen(46%)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;config(depth=10, elements=30, strlen=1):&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; serialize : time(0.767), length(116820)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; json&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : time(0.502), length(47610)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; diff: time(65%) | strlen(40%)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;config(depth=0, elements=8000, strlen=1):&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; serialize : time(0.445), length(71185)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; json&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : time(0.277), length(25943)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; diff: time(62%) | strlen(36%)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;config(depth=0, elements=8000, strlen=99):&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; serialize : time(0.784), length(289298)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; json&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : time(0.962), length(206929)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; diff: time(122%) | strlen(71%)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;config(depth=0, elements=8000, strlen=999):&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; serialize : time(1.371), length(1665092)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; json&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : time(5.630), length(1581304)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; diff: time(410%) | strlen(94%)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;config(depth=4, elements=30, strlen=99):&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; serialize : time(0.221), length(73598)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; json&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : time(0.265), length(54542)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; diff: time(119%) | strlen(74%)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;config(depth=4, elements=30, strlen=999):&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; serialize : time(0.018), length(30238)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; json&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp; : time(0.095), length(28817)&lt;/span&gt;&lt;br style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;" /&gt;&lt;span style="font-family: &amp;quot;Courier New&amp;quot;,Courier,monospace;"&gt;&amp;nbsp; diff: time(521%) | strlen(95%)&lt;/span&gt;&lt;/span&gt;&lt;/blockquote&gt;&lt;br /&gt;
Conclusión:&lt;br /&gt;
&lt;ul&gt;&lt;li&gt;Para datos que se deben serializar pero que únicamente van a ser accedidos por php, casi siempre será mejor usar la opción de serialize. Especialmente con variables que contendrán cadenas muy largas.&lt;br /&gt;
&lt;/li&gt;
&lt;li&gt;Si se requiere acceder a esos datos desde otros lenguajes o modificarlos manualmente, json es una buena opción. Si se van a serializar objetos complejos, json será siempre más compacto. Si la variable contendrá una cadena, o indirectamente alguna cadena, como elemento o clave de un array y son cadenas muy largas, json está penalizado.&lt;br /&gt;
&lt;/li&gt;
&lt;/ul&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1250738086120444710-2104404096498986846?l=php.soywiz.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/GE5TcVOoKNL12prEhppQIXqJao8/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/GE5TcVOoKNL12prEhppQIXqJao8/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/GE5TcVOoKNL12prEhppQIXqJao8/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/GE5TcVOoKNL12prEhppQIXqJao8/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://php.soywiz.com/feeds/2104404096498986846/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://php.soywiz.com/2009/04/serialize-o-jsonencode.html#comment-form" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1250738086120444710/posts/default/2104404096498986846?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1250738086120444710/posts/default/2104404096498986846?v=2" /><link rel="alternate" type="text/html" href="http://php.soywiz.com/2009/04/serialize-o-jsonencode.html" title="¿serialize o json_encode?" /><author><name>soywiz</name><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03708515771492521927" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;Dk8FSXg_cSp7ImA9WxZUEU4.&quot;"><id>tag:blogger.com,1999:blog-1250738086120444710.post-3482061338770829788</id><published>2008-03-31T01:24:00.010+02:00</published><updated>2008-04-02T13:13:38.649+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-04-02T13:13:38.649+02:00</app:edited><title>Usando y extendiendo PDO (I)</title><content type="html">PDO (PHP Data Objects) es una librería estándard disponible a partir de PHP5.0 como extensión PECL y en PHP5.1 como librería de serie que se puede usar para acceder a distintas bases de datos.&lt;br /&gt;&lt;br /&gt;Es un buen hábito usar los recursos del lenguaje sin dependencias adicionales, y en muchos servidores ya está disponible PHP5.2, así que disponer de PDO es bastante normal.&lt;br /&gt;&lt;br /&gt;PDO ofrece una interfaz orientada a objetos que se puede extender con facilidad.&lt;br /&gt;&lt;br /&gt;Existen numerosos ejemplos en internet sobre cómo usarla, así que no me extenderé en ello. Me centraré especialmente en cómo usar PDO para programar de forma sencilla y eficiente.&lt;br /&gt;&lt;br /&gt;PDO define dos clases: &lt;span style="font-weight: bold;"&gt;PDO&lt;/span&gt; y &lt;span style="font-weight: bold;"&gt;PDOStatement&lt;/span&gt;.&lt;br /&gt;&lt;br /&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Acceder al objeto PDO&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;Generalmente tendremos una única conexión con una base de datos y para acceder al objeto PDO de esa conexión desde cualquier sitio (incluido funciones) necesitaremos o bien una variable global o bien un campo estático con el objeto.&lt;br /&gt;&lt;br /&gt;Generalmente la gente suele optar por una variable global tipo $dblink o similares. Y para acceder a ella genéricamente desde una función o desde el ámbito global, necesitaremos acceder a ella con la superglobal $GLOBALS: $GLOBALS['dblink'] o explicitando su uso mediante el keyword global: global $dblink;&lt;br /&gt;&lt;br /&gt;Cualquiera de las dos soluciones es un poco engorrosa. Yo últimamente estoy usando la opción de campo estático y me está dando muy buenos resultados:&lt;br /&gt;&lt;br /&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;class &lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;db &lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;{&lt;br /&gt;    static &lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;$db&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;Para acceder al objeto PDO, bastaría con usar db::$db, que además de ser mas corto es mas fácil de escribir y tiene en parte un poco mas de sentido. Además usando la característica __autoload que ya he comentado, podemos hacer que se incluya a demanda la clase db y podemos hacer que en el fichero que esté definida la clase db, se encargue de hacer la conexión, de forma que mágicamente al acceder a db::$db obtendremos un objeto PDO con la conexión y si no, no se llegará a conectar (si no es necesario) y sin tener que estar con require_once o similares cada dos por tres.&lt;br /&gt;&lt;br /&gt;Además podemos usar la clase db para ciertas utilidades SQL. Es bastante habitual hacer inserts sencillos o updates que cambien una sola fila mediante un id y similares. Así que en class db. Me he puesto un par de métodos estáticos para generar queries de UPDATE e INSERT dada una tabla, un array asociativo y para el caso del UPDATE, una condición.&lt;br /&gt;&lt;br /&gt;En el caso del array asociativo del UPDATE tengo un caso especial que ocurre cuando el nombre de un campo empieza por '*', en cuyo caso el valor será una expresión (para cosas tipo NOW() y similares).&lt;span style="font-weight: bold;font-size:130%;" &gt;&lt;br /&gt;&lt;/span&gt;&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1250738086120444710-3482061338770829788?l=php.soywiz.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/Ebnj1d0Gs5EdnLZWI9WR50hau64/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Ebnj1d0Gs5EdnLZWI9WR50hau64/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/Ebnj1d0Gs5EdnLZWI9WR50hau64/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/Ebnj1d0Gs5EdnLZWI9WR50hau64/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://php.soywiz.com/feeds/3482061338770829788/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://php.soywiz.com/2008/03/usando-y-extendiendo-pdo-i.html#comment-form" title="1 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1250738086120444710/posts/default/3482061338770829788?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1250738086120444710/posts/default/3482061338770829788?v=2" /><link rel="alternate" type="text/html" href="http://php.soywiz.com/2008/03/usando-y-extendiendo-pdo-i.html" title="Usando y extendiendo PDO (I)" /><author><name>soywiz</name><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03708515771492521927" /></author><thr:total>1</thr:total></entry><entry gd:etag="W/&quot;A08NSHY5fip7ImA9WxZVGUw.&quot;"><id>tag:blogger.com,1999:blog-1250738086120444710.post-4282859892261435830</id><published>2008-03-31T01:04:00.011+02:00</published><updated>2008-03-31T01:31:39.826+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-03-31T01:31:39.826+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="autoload" /><category scheme="http://www.blogger.com/atom/ns#" term="php5" /><category scheme="http://www.blogger.com/atom/ns#" term="php" /><title>php5.1 y spl_autoload_register</title><content type="html">Desde &lt;span style="font-weight: bold;"&gt;php5.1&lt;/span&gt; disponemos de &lt;span style="font-weight: bold;"&gt;spl_autoload_register&lt;/span&gt; (desde &lt;span style="font-weight: bold;"&gt;php5.0&lt;/span&gt; podemos definir la función &lt;span style="font-weight: bold;"&gt;__autoload&lt;/span&gt;).&lt;br /&gt;&lt;br /&gt;En php5 si se define una función __autoload, ésta se llamará cada vez que se intente acceder a una clase que no exista. Tanto a un método estático como a la creación de un nuevo objeto de ese tipo.&lt;br /&gt;&lt;br /&gt;Ésto nos permite cargar código implícitamente y olvidarnos de incluir dependencias continuamente y permitiéndonos hacer algunas cosas mas lightweight sin tener que cargar cosas que no nos interesan.&lt;br /&gt;&lt;br /&gt;Aunque nos obliga a usar clases.&lt;br /&gt;&lt;br /&gt;Para agrupar funciones útiles que usemos comúnmente se puede hacer una clase "util" y luego métodos estáticos. Por ejemplo, yo suelo usar muy amenudo una función que llamo print_r_pre que se encarga de hacer lo mismo que un print_r, pero para que se vea correctamente en la web (usando &amp;lt;pre&amp;gt; y htmlspecialchars). Pues bien, me podría hacer una clase "util" con la función ahí:&lt;br /&gt;&lt;br /&gt;&lt;pre&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;class &lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;util &lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;{&lt;br /&gt; static function &lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;print_r_pre&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;$v&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;) {&lt;br /&gt;    echo &lt;/span&gt;&lt;span style="color: rgb(221, 0, 0);"&gt;'&lt;&gt;' &lt;span style="color: rgb(0, 119, 0);"&gt;. &lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;htmlspecialchars&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;print_r&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;$v&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;, &lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;true&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;)) . &lt;/span&gt;&lt;span style="color: rgb(221, 0, 0);"&gt;'&lt;/span&gt;&lt; /pre&gt;'&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;;&lt;br /&gt; }&lt;br /&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;Lo metería, por ejemplo, en un fichero llamado &lt;span style="font-weight: bold;"&gt;util.php&lt;/span&gt; en una carpeta creada para usar con la característica __autoload. Por ejemplo: /core/classes/util.php&lt;br /&gt;&lt;br /&gt;Y luego en un fichero que sí que debería cargar cada vez algo tipo esto (suponiendo que el fichero que inclue este código esté en /core/):&lt;br /&gt;&lt;pre&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;function &lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;__autoload&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;$class&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;) {&lt;br /&gt; if (!&lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;file_exists&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;$file &lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;= &lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;dirname&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;__FILE__&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;) . &lt;/span&gt;&lt;span style="color: rgb(221, 0, 0);"&gt;'/classes/' &lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;. &lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;$class &lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;. &lt;/span&gt;&lt;span style="color: rgb(221, 0, 0);"&gt;'.php'&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;))    return;&lt;br /&gt; require_once(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;$file&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;);&lt;br /&gt;}&lt;/span&gt;&lt;/span&gt;&lt;/pre&gt;&lt;span style="font-family: monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="font-size:130%;"&gt;&lt;span style="font-weight: bold;"&gt;Conclusión:&lt;/span&gt;&lt;/span&gt;&lt;br /&gt;Si estás usando php5 y quieres ahorrarte mogollón de &lt;span style="font-weight: bold;"&gt;requiere_once&lt;/span&gt;. Las soluciones __autoload son para tí.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1250738086120444710-4282859892261435830?l=php.soywiz.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/wVJE3Q7bP7BLTNqX-Oghs3i1r-A/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/wVJE3Q7bP7BLTNqX-Oghs3i1r-A/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/wVJE3Q7bP7BLTNqX-Oghs3i1r-A/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/wVJE3Q7bP7BLTNqX-Oghs3i1r-A/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://php.soywiz.com/feeds/4282859892261435830/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://php.soywiz.com/2008/03/blog-post.html#comment-form" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1250738086120444710/posts/default/4282859892261435830?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1250738086120444710/posts/default/4282859892261435830?v=2" /><link rel="alternate" type="text/html" href="http://php.soywiz.com/2008/03/blog-post.html" title="php5.1 y spl_autoload_register" /><author><name>soywiz</name><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03708515771492521927" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;CU4NQ3w4eSp7ImA9WxZVGU8.&quot;"><id>tag:blogger.com,1999:blog-1250738086120444710.post-7138811722234084507</id><published>2008-03-30T20:38:00.015+02:00</published><updated>2008-03-31T02:39:52.231+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-03-31T02:39:52.231+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="texto" /><category scheme="http://www.blogger.com/atom/ns#" term="php" /><title>echo vs printf vs strtr/str_(i)replace vs preg_replace_callback</title><content type="html">&lt;span style="font-weight: bold;font-size:130%;" &gt;Introducción:&lt;/span&gt;&lt;br /&gt;&lt;br /&gt;En muchas ocasiones querremos separar el texto de nuestras páginas web de la programación propiamente dicho. En ocasiones será para poder localizar nuestra página (tenerla en diferentes idiomas), otras simplemente por comodidad.&lt;br /&gt;&lt;br /&gt;Dichos textos, generalmente estarán mezclados con contenido dinámico que se tendrá que reemplazar.&lt;br /&gt;&lt;div style="text-align: justify;"&gt;&lt;br /&gt;Supongamos que tenemos una página con categorías y entradas de algún tipo y queremos mostrar en el título el camino a una subcategoría, y la cantidad de subcategorías y de elementos que tiene.&lt;br /&gt;&lt;br /&gt;Podríamos hacer algo similar a esto usando &lt;span style="font-weight: bold;"&gt;echo&lt;/span&gt;:&lt;br /&gt;&lt;span style="font-family:monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;div style="text-align: left;"&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;echo &lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;htmlspecialchars&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(221, 0, 0);"&gt;'Categoría: ' &lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;. &lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;implode&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(221, 0, 0);"&gt;' &gt; '&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;, &lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;$path&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;) . &lt;/span&gt;&lt;span style="color: rgb(221, 0, 0);"&gt;' Subcategorías: ' &lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;. (int)&lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;$categories_count &lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;. &lt;/span&gt;&lt;span style="color: rgb(221, 0, 0);"&gt;' Entradas: ' &lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;. (int)&lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;$entries_count&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;);&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;code&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&lt;/code&gt;&lt;/div&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;&lt;span style="font-size:85%;"&gt;&lt;span style="font-family:courier new;"&gt;&lt;/span&gt;&lt;/span&gt;&lt;div style="text-align: justify;"&gt;No es difíl darse cuenta de que, aunque funciona, es difícilmente actualizable; especialmente si la persona que tiene que retocarlo no sabe programar. Además si quisiesemos traducirlo a otros idiomas tendríamos que traducir cada parte individualmente (con el echo).&lt;br /&gt;&lt;br /&gt;Otra alternativa es usar la función printf, que permite crear una cadena de formato separada de los datos y nos permite una separación cómoda y eficiente; además de que facilita mucho todo lo referente a la localización de texto.&lt;br /&gt;&lt;br /&gt;Con &lt;span style="font-weight: bold;"&gt;printf&lt;/span&gt;, podríamos hacer algo similar a esto:&lt;br /&gt;&lt;br /&gt;&lt;div style="text-align: left;"&gt;&lt;span style="font-family:courier new;"&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;&lt;span style="color: rgb(0, 119, 0);font-size:100%;" &gt;define(&lt;/span&gt;&lt;span style="color: rgb(221, 0, 0);font-size:100%;" &gt;'TITLE_CATEGORY'&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);font-size:100%;" &gt;,&lt;/span&gt;&lt;span style="color: rgb(221, 0, 0);font-size:100%;" &gt;'Categoría: %s Subcategorías: %d Entradas: %d'&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);font-size:100%;" &gt;);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/span&gt;&lt;br /&gt;&lt;span style="font-family:courier new;"&gt;&lt;code&gt;&lt;/code&gt;&lt;/span&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;printf&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;TITLE_CATEGORY&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;, &lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;implode&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(221, 0, 0);"&gt;' &amp;gt; '&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;, &lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;$path&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;), (int)&lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;$categories_count&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;, (int)&lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;$entries_count&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;));&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;/div&gt;&lt;span style="font-family:monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;/div&gt;&lt;span style="font-family:courier new;"&gt;&lt;/span&gt;&lt;div style="text-align: justify;"&gt;El define (o una posible variable global o clave en un array), puede estar en un fichero distinto con todos los textos a localizar o a modificar de fácil acceso. También puede estar en una base de datos o en un fichero de texto que pueda editar otra persona. Además nos permitiría dar formato a los números o a las cadenas.&lt;br /&gt;&lt;br /&gt;Por otra parte perdemos la posibilidad de cambiar de orden los elementos. El printf requiere que los elementos estén en orden.&lt;br /&gt;&lt;br /&gt;Con &lt;span style="font-weight: bold;"&gt;strtr&lt;/span&gt; o con &lt;span style="font-weight: bold;"&gt;str_replace&lt;/span&gt; o &lt;span style="font-weight: bold;"&gt;str_ireplace&lt;/span&gt; podemos conseguir una "cadena de formato" que permita cambiar el orden de los elementos de una forma ligera y eficiente:&lt;br /&gt;&lt;span style="font-family:monospace;"&gt;&lt;br /&gt;&lt;/span&gt;&lt;div style="text-align: left;"&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;&lt;span style="color: rgb(0, 119, 0);font-size:100%;" &gt;define(&lt;/span&gt;&lt;span style="color: rgb(221, 0, 0);font-size:100%;" &gt;'TITLE_CATEGORY'&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);font-size:100%;" &gt;, &lt;/span&gt;&lt;span style="color: rgb(221, 0, 0);font-size:100%;" &gt;'Categoría: {categories} Subcategorías: {categories_count} Entradas: {entries_count}'&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);font-size:100%;" &gt;);&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;&lt;span style="color: rgb(0, 119, 0);font-size:100%;" &gt;echo &lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);font-size:100%;" &gt;htmlspecialchars&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);font-size:100%;" &gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);font-size:100%;" &gt;strtr&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);font-size:100%;" &gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);font-size:100%;" &gt;TITLE_CATEGORY&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);font-size:100%;" &gt;, array(&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;&lt;span style="color: rgb(0, 119, 0);font-size:100%;" &gt;  &lt;/span&gt;&lt;span style="color: rgb(221, 0, 0);font-size:100%;" &gt;'{categories}'       &lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);font-size:100%;" &gt;=&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);font-size:100%;" &gt;implode&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);font-size:100%;" &gt;(&lt;/span&gt;&lt;span style="color: rgb(221, 0, 0);font-size:100%;" &gt;' &gt; '&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);font-size:100%;" &gt;, &lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);font-size:100%;" &gt;$path&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);font-size:100%;" &gt;),&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;&lt;span style="color: rgb(0, 119, 0);font-size:100%;" &gt;  &lt;/span&gt;&lt;span style="color: rgb(221, 0, 0);font-size:100%;" &gt;'{categories_rev}'   &lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);font-size:100%;" &gt;=&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);font-size:100%;" &gt;implode&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);font-size:100%;" &gt;(&lt;/span&gt;&lt;span style="color: rgb(221, 0, 0);font-size:100%;" &gt;' &lt; '&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);font-size:100%;" &gt;, &lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);font-size:100%;" &gt;array_reverse&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);font-size:100%;" &gt;)(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);font-size:100%;" &gt;$path&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);font-size:100%;" &gt;)),&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;&lt;span style="color: rgb(0, 119, 0);font-size:100%;" &gt;  &lt;/span&gt;&lt;span style="color: rgb(221, 0, 0);font-size:100%;" &gt;'{categories_count}' &lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);font-size:100%;" &gt;=&gt; (int)&lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);font-size:100%;" &gt;$categories_count&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);font-size:100%;" &gt;,&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;&lt;span style="color: rgb(0, 119, 0);font-size:100%;" &gt;  &lt;/span&gt;&lt;span style="color: rgb(221, 0, 0);font-size:100%;" &gt;'{entries_count}'    &lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);font-size:100%;" &gt;=&gt; (int)&lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);font-size:100%;" &gt;$entries_count&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);font-size:85%;" &gt;&lt;span style="font-size:100%;"&gt;)&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;&lt;span style="color: rgb(0, 119, 0);font-size:85%;" &gt;&lt;span style="font-size:100%;"&gt;)));&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;br /&gt;&lt;code&gt;&lt;/code&gt;&lt;/div&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;&lt;span style="color: rgb(0, 119, 0);font-size:85%;" &gt;&lt;br /&gt;&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/div&gt;&lt;span style="font-family:courier new;"&gt;&lt;/span&gt;&lt;div style="text-align: justify;"&gt;Se puede ver que he añadido una opción &lt;span style="font-weight: bold;"&gt;categories_rev&lt;/span&gt;, por si la persona que se encarga de traducir o de retocar los textos de la página determina que sería interesante colocar las categorías mas internas antes que las mas generales (por ejemplo para optimización para motores de búsqueda). Con &lt;span style="font-weight: bold;"&gt;prg_(i)replace&lt;/span&gt;, podríamos conseguir el mismo efecto que con strtr, si en vez de usar un array asociativa, usamos dos arrays, uno con las claves y otro con los valores.&lt;br /&gt;&lt;br /&gt;Para finalizar decir que con &lt;span style="font-weight: bold;"&gt;preg_replace&lt;/span&gt; y &lt;span style="font-weight: bold;"&gt;preg_replace_callback&lt;/span&gt;, podemos conseguir un reemplazado mucho mas potente, aunque algo mas complejo y lento. Pondré un ejemplo en el que se nos permite aplicar una función a un parámetro y obtener los parámetros:&lt;br /&gt;&lt;div style="text-align: left;"&gt;&lt;pre class="phpcode"&gt;&lt;code&gt;&lt;span style="color: rgb(0, 0, 0);"&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;function &lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;my_function&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;$v&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;) {&lt;br /&gt;return &lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;strtr&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;$v&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;, &lt;/span&gt;&lt;span style="color: rgb(221, 0, 0);"&gt;'aeios'&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;, &lt;/span&gt;&lt;span style="color: rgb(221, 0, 0);"&gt;'43105'&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function &lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;my_replace_callback&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;$k&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;) {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;$rl    &lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;= &amp;amp;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;$GLOBALS&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;[&lt;/span&gt;&lt;span style="color: rgb(221, 0, 0);"&gt;'my_replace_list'&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;];&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;$funcs &lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;= &amp;amp;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;$GLOBALS&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;[&lt;/span&gt;&lt;span style="color: rgb(221, 0, 0);"&gt;'my_replace_list_funcs'&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;];&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;$k &lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;= &lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;explode&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(221, 0, 0);"&gt;':'&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;, &lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;$k&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;[&lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;1&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;]);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;$key &lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;= &lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;array_shift&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;$k&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;);&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;$r &lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;= isset(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;$rl&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;[&lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;$key&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;]) ? &lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;$rl&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;[&lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;$key&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;] : &lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;$key&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;;&lt;br /&gt;&lt;br /&gt;while (&lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;sizeof&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;$k&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;)) {&lt;br /&gt;   &lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;$func &lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;= &lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;array_shift&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;$k&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;);&lt;br /&gt;   if (&lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;in_array&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;$func&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;, &lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;$funcs&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;)) &lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;$r &lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;= &lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;$func&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;$r&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;return &lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;$r&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;;&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;function &lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;my_replace&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;$t&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;, &lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;$l&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;, &lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;$f&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;) {&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;$GLOBALS&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;[&lt;/span&gt;&lt;span style="color: rgb(221, 0, 0);"&gt;'my_replace_list'&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;] = &lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;$l&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;$GLOBALS&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;[&lt;/span&gt;&lt;span style="color: rgb(221, 0, 0);"&gt;'my_replace_list_funcs'&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;] = &lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;$f&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;;&lt;br /&gt;return &lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;preg_replace_callback&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(221, 0, 0);"&gt;'/\\{([^\\}]+)\\}/'&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;, &lt;/span&gt;&lt;span style="color: rgb(221, 0, 0);"&gt;'my_replace_callback'&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;, &lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;$t&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;);&lt;br /&gt;}&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;$path &lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;= array(&lt;/span&gt;&lt;span style="color: rgb(221, 0, 0);"&gt;'objetos'&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;, &lt;/span&gt;&lt;span style="color: rgb(221, 0, 0);"&gt;'inanimados'&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;, &lt;/span&gt;&lt;span style="color: rgb(221, 0, 0);"&gt;'escolar'&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;, &lt;/span&gt;&lt;span style="color: rgb(221, 0, 0);"&gt;'escritura'&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;);&lt;br /&gt;&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;define&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(221, 0, 0);"&gt;'TITLE_CATEGORY'&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;, &lt;/span&gt;&lt;span style="color: rgb(221, 0, 0);"&gt;'Categoría: {categories:my_function:strtoupper} Subcategorías: {categories_count} Entradas: {entries_count}'&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;);&lt;br /&gt;&lt;br /&gt;echo &lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;htmlspecialchars&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;my_replace&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;TITLE_CATEGORY&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;, array(&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(221, 0, 0);"&gt;'categories'       &lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;=&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;implode&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(221, 0, 0);"&gt;' &gt; '&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;, &lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;$path&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;),&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(221, 0, 0);"&gt;'categories_rev'   &lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;=&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;implode&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(221, 0, 0);"&gt;' &lt; '&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;, &lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;array_reverse&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;(&lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;$path&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;)),&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(221, 0, 0);"&gt;'categories_count' &lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;=&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;10&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;,&lt;br /&gt;&lt;/span&gt;&lt;span style="color: rgb(221, 0, 0);"&gt;'entries_count'    &lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;=&gt; &lt;/span&gt;&lt;span style="color: rgb(0, 0, 187);"&gt;100&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;,&lt;br /&gt;), array(&lt;/span&gt;&lt;span style="color: rgb(221, 0, 0);"&gt;'strtoupper'&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;, &lt;/span&gt;&lt;span style="color: rgb(221, 0, 0);"&gt;'trim'&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;, &lt;/span&gt;&lt;span style="color: rgb(221, 0, 0);"&gt;'my_function'&lt;/span&gt;&lt;span style="color: rgb(0, 119, 0);"&gt;)));&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;/div&gt;&lt;span style="font-weight: bold;font-size:130%;" &gt;Conclusión:&lt;/span&gt;&lt;br /&gt;&lt;ul&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;echo &lt;/span&gt;es práctico y rápido para cosas sencillas que no requieran formato y que no se tengan que modificar o traducir.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;printf &lt;/span&gt;es práctico para cadenas que requieran formato y una localización sencilla.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;echo+strtr &lt;/span&gt;nos permite dar un formato ligero pero más potente que las otras dos opciones.&lt;/li&gt;&lt;li&gt;&lt;span style="font-weight: bold;"&gt;echo+preg_replace_callback&lt;/span&gt; nos permite dar un formato mas pesado, pero tremendamente flexible, útil incluso para templates.&lt;/li&gt;&lt;/ul&gt;Generalmente &lt;span style="font-weight: bold;"&gt;echo+strtr&lt;/span&gt; suele dar muy buenos resultados para localización de texto, y ofrece un código compacto de bastante rendimiento y sin ninguna dependencia adicional.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1250738086120444710-7138811722234084507?l=php.soywiz.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/3Li0ZPOq-TtiBDE6YGnzpnljvrs/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/3Li0ZPOq-TtiBDE6YGnzpnljvrs/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/3Li0ZPOq-TtiBDE6YGnzpnljvrs/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/3Li0ZPOq-TtiBDE6YGnzpnljvrs/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://php.soywiz.com/feeds/7138811722234084507/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://php.soywiz.com/2008/03/echo-vs-printf-vs-strtrstrireplace-vs.html#comment-form" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1250738086120444710/posts/default/7138811722234084507?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1250738086120444710/posts/default/7138811722234084507?v=2" /><link rel="alternate" type="text/html" href="http://php.soywiz.com/2008/03/echo-vs-printf-vs-strtrstrireplace-vs.html" title="echo vs printf vs strtr/str_(i)replace vs preg_replace_callback" /><author><name>soywiz</name><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03708515771492521927" /></author><thr:total>0</thr:total></entry><entry gd:etag="W/&quot;CU4BRHozcSp7ImA9WxZVGU8.&quot;"><id>tag:blogger.com,1999:blog-1250738086120444710.post-4732080001499326195</id><published>2008-03-30T19:15:00.002+02:00</published><updated>2008-03-31T02:39:15.489+02:00</updated><app:edited xmlns:app="http://www.w3.org/2007/app">2008-03-31T02:39:15.489+02:00</app:edited><category scheme="http://www.blogger.com/atom/ns#" term="php" /><category scheme="http://www.blogger.com/atom/ns#" term="general" /><title>Introducción</title><content type="html">Nuevo blog de programación en PHP.&lt;br /&gt;&lt;blockquote&gt;Tras largos años de experiencia con PHP he ido enfrentándome a numerosos problemas que he ido resolviendo cada vez mejor. He desarrollado técnicas para montar páginas en php ligeras, eficientes y robustas.&lt;br /&gt;&lt;br /&gt;Internet está repleta de información sobre la programación en PHP, pero hay poca información sobre buenos hábitos, y técnicas de programación avanzadas y la poca que hay está en inglés.&lt;/blockquote&gt;Este blog tratará sobre programación avanzada en PHP y técnicas para hacer una programación sencilla y eficiente.&lt;br /&gt;&lt;br /&gt;Explicaré también algunas técnicas nuevas que he desarrollado para el relativamente reciente PHP5 y sus nuevas características. Aunque muchas de las técnicas serán compatibles tanto con PHP5 como con el antiguo PHP4. No trataré temas de PHP3 ni por supuesto PHP/FI.&lt;div class="blogger-post-footer"&gt;&lt;img width='1' height='1' src='https://blogger.googleusercontent.com/tracker/1250738086120444710-4732080001499326195?l=php.soywiz.com' alt='' /&gt;&lt;/div&gt;
&lt;p&gt;&lt;a href="http://feedads.g.doubleclick.net/~a/vlN_7r3EiwlGk9xUJUDwWvjZgY4/0/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/vlN_7r3EiwlGk9xUJUDwWvjZgY4/0/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;br/&gt;
&lt;a href="http://feedads.g.doubleclick.net/~a/vlN_7r3EiwlGk9xUJUDwWvjZgY4/1/da"&gt;&lt;img src="http://feedads.g.doubleclick.net/~a/vlN_7r3EiwlGk9xUJUDwWvjZgY4/1/di" border="0" ismap="true"&gt;&lt;/img&gt;&lt;/a&gt;&lt;/p&gt;</content><link rel="replies" type="application/atom+xml" href="http://php.soywiz.com/feeds/4732080001499326195/comments/default" title="Enviar comentarios" /><link rel="replies" type="text/html" href="http://php.soywiz.com/2008/03/introduccin.html#comment-form" title="0 comentarios" /><link rel="edit" type="application/atom+xml" href="http://www.blogger.com/feeds/1250738086120444710/posts/default/4732080001499326195?v=2" /><link rel="self" type="application/atom+xml" href="http://www.blogger.com/feeds/1250738086120444710/posts/default/4732080001499326195?v=2" /><link rel="alternate" type="text/html" href="http://php.soywiz.com/2008/03/introduccin.html" title="Introducción" /><author><name>soywiz</name><email>noreply@blogger.com</email><gd:extendedProperty name="OpenSocialUserId" value="03708515771492521927" /></author><thr:total>0</thr:total></entry></feed>
