<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>PHPBSD.net &#187; tostring</title>
	<atom:link href="http://www.phpbsd.net/tag/tostring/feed/" rel="self" type="application/rss+xml" />
	<link>http://www.phpbsd.net</link>
	<description>Blogueando sobre PHP, BSD, SEO, AJAX, Seguridad, Rendimiento... y mucho más</description>
	<lastBuildDate>Thu, 07 Oct 2010 11:57:22 +0000</lastBuildDate>
	<generator>http://wordpress.org/?v=2.8.6</generator>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
			<item>
		<title>Interesantes usos y alternativas de __toString() en PHP 5.x</title>
		<link>http://www.phpbsd.net/2009/04/02/interesantes-usos-y-alternativas-de-__tostring-en-php-5x/</link>
		<comments>http://www.phpbsd.net/2009/04/02/interesantes-usos-y-alternativas-de-__tostring-en-php-5x/#comments</comments>
		<pubDate>Wed, 01 Apr 2009 23:50:19 +0000</pubDate>
		<dc:creator>Oriol</dc:creator>
				<category><![CDATA[Artículos]]></category>
		<category><![CDATA[oop]]></category>
		<category><![CDATA[php]]></category>
		<category><![CDATA[programación]]></category>
		<category><![CDATA[symfony]]></category>
		<category><![CDATA[tostring]]></category>
		<category><![CDATA[webmaster]]></category>

		<guid isPermaLink="false">http://www.phpbsd.net/?p=143</guid>
		<description><![CDATA[Desde la llegada de PHP 5.0 disponemos de varios métodos mágicos para nuestras clases PHP, entre ellos tenemos __toString() que nos permite codificar cómo queremos que se comporte una clase cuando una instancia de ella se convierte a un string.
Aunque a simple vista el método __toString() pueda parecer poco importante en PHP éste toma mucha [...]


Entradas relacionadas:<ul><li><a href='http://www.phpbsd.net/2007/01/13/un-error-handler-que-lance-exceptions-en-php/' rel='bookmark' title='Permanent Link: Un error handler que lance exceptions en PHP'>Un error handler que lance exceptions en PHP</a></li><li><a href='http://www.phpbsd.net/2007/01/11/urls-limpias-y-amigables-con-php-y-apache/' rel='bookmark' title='Permanent Link: URLs limpias y amigables con PHP y Apache'>URLs limpias y amigables con PHP y Apache</a></li><li><a href='http://www.phpbsd.net/2007/04/25/carga-automatica-de-clases-en-php-con-autoload/' rel='bookmark' title='Permanent Link: Carga automática de clases en PHP con autoload'>Carga automática de clases en PHP con autoload</a></li></ul>]]></description>
			<content:encoded><![CDATA[<p>Desde la llegada de PHP 5.0 disponemos de varios <strong>métodos mágicos</strong> para nuestras clases PHP, entre ellos tenemos <a target="_blank" title="PHP: Magic Methods - Manual" href="http://www.php.net/manual/en/language.oop5.magic.php#language.oop5.magic.tostring">__toString()</a> que nos permite codificar cómo queremos que se comporte una clase cuando una instancia de ella se convierte a un string.</p>
<p>Aunque a simple vista el método <em>__toString()</em> pueda parecer poco importante en PHP éste toma mucha relevancia si trabajamos con <a target="_blank" title="symfony | Web PHP Framework" href="http://www.symfony-project.org/">symfony</a> o algún otro <strong>framework orientado a objetos</strong> donde la información de la base datos se encuentra mapeada en un modelo de objetos.</p>
<p>A pesar de que <em>__toString()</em> está disponible desde la versión 5.0.0 del PHP en mi opinión <strong>no empieza a ser realmente útil hasta la versión 5.2.0</strong>, algo que en el <a target="_blank" title="PHP: PHP 5 ChangeLog" href="http://www.php.net/ChangeLog-5.php#5.2.0">changelog del PHP</a> reflejaron con un tímido:</p>
<blockquote><p>Changed __toString() to be called wherever applicable. (Marcus)</p></blockquote>
<p>Hasta entonces <em>__toString()</em> sólo se llamaba cuando se usaba <em>echo()</em> o <em>print()</em> lo que limitaba mucho su funcionalidad. Desde la versión 5.2.0 <em>__toString()</em> se llama siempre que tratemos a un objeto como a un string.</p>
<p>Por ejemplo dada la siguiente definición de clase:</p>
<div class="syntax_hilite">
<div id="php-6">
<div class="php"><span style="color:#000000; font-weight:bold;">class</span> User extends BaseUser<br />
<span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; public <span style="color:#000000; font-weight:bold;">function</span> __toString<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; <span style="color:#616100;">return</span> <span style="color:#0000FF;">$this</span>-&gt;<span style="color:#006600;">getName</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><br />
<span style="color:#006600; font-weight:bold;">&#125;</span></div>
</div>
</div>
<p></p>
<p>Hasta PHP 5.2.0 sólo podíamos invocar a <em>__toString()</em> con:</p>
<div class="syntax_hilite">
<div id="php-7">
<div class="php"><span style="color:#0000FF;">$user</span> = <span style="color:#000000; font-weight:bold;">new</span> User<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
<a href="http://www.php.net/echo"><span style="color:#000066;">echo</span></a> <span style="color:#0000FF;">$user</span>;<br />
<a href="http://www.php.net/print"><span style="color:#000066;">print</span></a> <span style="color:#0000FF;">$user</span>;</div>
</div>
</div>
<p></p>
<p>Desde la versión 5.2.0 podemos hacer varias cosas interesantes con <em>__toString()</em> sobretodo relacionadas con el manejo de arrays de objetos, algo muy frecuente en los frameworks que corren por ahí hoy en día.</p>
<p>Por ejemplo si obtenemos el típico array de objetos con symfony:</p>
<div class="syntax_hilite">
<div id="php-8">
<div class="php"><span style="color:#0000FF;">$users</span> = UserPeer::<span style="color:#006600;">doSelect</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#000000; font-weight:bold;">new</span> Criteria<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</div>
</div>
<p></p>
<p>Trabajando directamente con las funciones de PHP entre otras muchas cosas podemos:</p>
<ul>
<li>Ordenar el array de objetos con un simple <em>sort()</em></li>
<li>Eliminar objetos duplicados del array con un <em>array_unique()</em></li>
<li>Generar una lista separada por comas para la presentación con un <em>implode()</em></li>
<li>Buscar un objeto determinado dentro del array con <em>array_search()</em></li>
</ul>
<h4>Alternativas a __toString()</h4>
<p>Si no tenemos la suerte de trabajar con PHP 5.2.x, o si queremos poder trabajar con un método distinto de <em>__toString()</em> para determinadas operaciones con arrays de objetos, podemos usar un código parecido al que propongo a continuación:</p>
<div class="syntax_hilite">
<div id="php-9">
<div class="php"><span style="color:#000000; font-weight:bold;">class</span> objectTools<br />
<span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; protected <a href="http://www.php.net/static"><span style="color:#000066;">static</span></a> <span style="color:#000000; font-weight:bold;">function</span> getMethodValues<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$list</span>, <span style="color:#0000FF;">$method</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; <span style="color:#0000FF;">$items</span> = <a href="http://www.php.net/array"><span style="color:#000066;">array</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color:#616100;">foreach</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$list</span> <span style="color:#616100;">as</span> <span style="color:#0000FF;">$key</span> =&gt; <span style="color:#0000FF;">$obj</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$items</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#0000FF;">$key</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#0000FF;">$obj</span>-&gt;<span style="color:#0000FF;">$method</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color:#616100;">return</span> <span style="color:#0000FF;">$items</span>;<br />
&nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><br />
&nbsp; protected <a href="http://www.php.net/static"><span style="color:#000066;">static</span></a> <span style="color:#000000; font-weight:bold;">function</span> getObjectList<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$items</span>, <span style="color:#0000FF;">$list</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; <span style="color:#0000FF;">$ret</span> = <a href="http://www.php.net/array"><span style="color:#000066;">array</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color:#616100;">foreach</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$items</span> <span style="color:#616100;">as</span> <span style="color:#0000FF;">$key</span> =&gt; <span style="color:#0000FF;">$item</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color:#0000FF;">$ret</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#006600; font-weight:bold;">&#93;</span> = <span style="color:#0000FF;">$list</span><span style="color:#006600; font-weight:bold;">&#91;</span><span style="color:#0000FF;">$key</span><span style="color:#006600; font-weight:bold;">&#93;</span>;<br />
&nbsp; &nbsp; <span style="color:#616100;">return</span> <span style="color:#0000FF;">$ret</span>;<br />
&nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><br />
&nbsp; public <a href="http://www.php.net/static"><span style="color:#000066;">static</span></a> <span style="color:#000000; font-weight:bold;">function</span> arraySortByMethod<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$list</span>, <span style="color:#0000FF;">$method</span>, <span style="color:#0000FF;">$sort</span>=<span style="color:#FF0000;">'desc'</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; <span style="color:#0000FF;">$items</span> = self::<span style="color:#006600;">getMethodValues</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$list</span>, <span style="color:#0000FF;">$method</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; <a href="http://www.php.net/asort"><span style="color:#000066;">asort</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$items</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color:#616100;">if</span> <span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$sort</span>==<span style="color:#FF0000;">'desc'</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; &nbsp; &nbsp; <span style="color:#616100;">return</span> <a href="http://www.php.net/array_values"><span style="color:#000066;">array_values</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><a href="http://www.php.net/array_reverse"><span style="color:#000066;">array_reverse</span></a><span style="color:#006600; font-weight:bold;">&#40;</span>self::<span style="color:#006600;">getObjectList</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$items</span>, <span style="color:#0000FF;">$list</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color:#616100;">return</span> self::<span style="color:#006600;">getObjectList</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$items</span>, <span style="color:#0000FF;">$list</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><br />
&nbsp; public <a href="http://www.php.net/static"><span style="color:#000066;">static</span></a> <span style="color:#000000; font-weight:bold;">function</span> arrayUniqueByMethod<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$list</span>, <span style="color:#0000FF;">$method</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; <span style="color:#0000FF;">$items</span> = self::<span style="color:#006600;">getMethodValues</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$list</span>, <span style="color:#0000FF;">$method</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color:#616100;">return</span> self::<span style="color:#006600;">getObjectList</span><span style="color:#006600; font-weight:bold;">&#40;</span><a href="http://www.php.net/array_unique"><span style="color:#000066;">array_unique</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$items</span><span style="color:#006600; font-weight:bold;">&#41;</span>, <span style="color:#0000FF;">$list</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><br />
&nbsp; public <a href="http://www.php.net/static"><span style="color:#000066;">static</span></a> <span style="color:#000000; font-weight:bold;">function</span> arrayImplodeByMethod<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$list</span>, <span style="color:#0000FF;">$method</span>, <span style="color:#0000FF;">$sep</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; <span style="color:#0000FF;">$items</span> = self::<span style="color:#006600;">getMethodValues</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$list</span>, <span style="color:#0000FF;">$method</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color:#616100;">return</span> <a href="http://www.php.net/implode"><span style="color:#000066;">implode</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$sep</span>, <span style="color:#0000FF;">$items</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><br />
&nbsp; public <a href="http://www.php.net/static"><span style="color:#000066;">static</span></a> <span style="color:#000000; font-weight:bold;">function</span> arraySearchByMethod<span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$list</span>, <span style="color:#0000FF;">$method</span>, <span style="color:#0000FF;">$needle</span><span style="color:#006600; font-weight:bold;">&#41;</span><br />
&nbsp; <span style="color:#006600; font-weight:bold;">&#123;</span><br />
&nbsp; &nbsp; <span style="color:#0000FF;">$items</span> = self::<span style="color:#006600;">getMethodValues</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$list</span>, <span style="color:#0000FF;">$method</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; &nbsp; <span style="color:#616100;">return</span> <a href="http://www.php.net/array_search"><span style="color:#000066;">array_search</span></a><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$needle</span>, <span style="color:#0000FF;">$items</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
&nbsp; <span style="color:#006600; font-weight:bold;">&#125;</span><br />
<span style="color:#006600; font-weight:bold;">&#125;</span></div>
</div>
</div>
<p></p>
<p>Lo anterior es más una propuesta de código que algo decente para ser distribuido. Simplemente se trata de trabajar con un array temporal para almacenar los valores del método solicitado, correr la función PHP y, si es necesario, volver a construir el array de objetos.</p>
<p>Algunos ejemplos de uso:</p>
<div class="syntax_hilite">
<div id="php-10">
<div class="php"><span style="color:#0000FF;">$ordenados</span> = objectTools::<span style="color:#006600;">arraySortByMethod</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$users</span>, <span style="color:#FF0000;">'getName'</span>, <span style="color:#FF0000;">'asc'</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
<span style="color:#0000FF;">$sin_duplicados</span> = objectTools::<span style="color:#006600;">arrayUniqueByMethod</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$users</span>, <span style="color:#FF0000;">'getName'</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
<span style="color:#0000FF;">$pos</span> = objectTools::<span style="color:#006600;">arraySearchByMethod</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$users</span>, <span style="color:#FF0000;">'getName'</span>, <span style="color:#FF0000;">'oriol'</span><span style="color:#006600; font-weight:bold;">&#41;</span>;<br />
<span style="color:#FF9933; font-style:italic;">//y por último en una plantilla...</span><br />
<a href="http://www.php.net/echo"><span style="color:#000066;">echo</span></a> <span style="color:#FF0000;">'Usuarios: '</span> . objectTools::<span style="color:#006600;">arrayImplodeByMethod</span><span style="color:#006600; font-weight:bold;">&#40;</span><span style="color:#0000FF;">$users</span>, <span style="color:#FF0000;">'getName'</span>, <span style="color:#FF0000;">', '</span><span style="color:#006600; font-weight:bold;">&#41;</span>;</div>
</div>
</div>
<p></p>
<p>Fácilmente se pueden añadir tantos métodos de tratamiento de arrays como se necesiten... o mucho mejor hacer un método que simplemente reciba como variable la función PHP a ejecutar. En mi caso de momento sólo necesito estos en concreto y también así los puedo controlar individualmente.</p>
<p>Aunque estos métodos de <strong>objectTools</strong> nacieron como "parche" rápido dado que no tenía PHP 5.2.x para un proyecto symfony, ahora, una vez solventando el problema con los servidores, los sigo encontrando útiles en múltiples situaciones. Por supuesto se ha de tener presente el poco rendimiento de este código frente a realizar queries a medida usando el objeto Criteria, pero si ya tenemos un array de objetos en memoria sí que será más óptimo trabajar con él en lugar de lanzar varias queries contra la base de datos.</p>


<p>Entradas relacionadas:<ul><li><a href='http://www.phpbsd.net/2007/01/13/un-error-handler-que-lance-exceptions-en-php/' rel='bookmark' title='Permanent Link: Un error handler que lance exceptions en PHP'>Un error handler que lance exceptions en PHP</a></li><li><a href='http://www.phpbsd.net/2007/01/11/urls-limpias-y-amigables-con-php-y-apache/' rel='bookmark' title='Permanent Link: URLs limpias y amigables con PHP y Apache'>URLs limpias y amigables con PHP y Apache</a></li><li><a href='http://www.phpbsd.net/2007/04/25/carga-automatica-de-clases-en-php-con-autoload/' rel='bookmark' title='Permanent Link: Carga automática de clases en PHP con autoload'>Carga automática de clases en PHP con autoload</a></li></ul></p>]]></content:encoded>
			<wfw:commentRss>http://www.phpbsd.net/2009/04/02/interesantes-usos-y-alternativas-de-__tostring-en-php-5x/feed/</wfw:commentRss>
		<slash:comments>1</slash:comments>
		</item>
	</channel>
</rss>

