<?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>KumbiaPHP Framework PHP en español</title>
	<atom:link href="https://kumbiaphp.com/blog/feed/" rel="self" type="application/rss+xml" />
	<link>https://kumbiaphp.com/blog/</link>
	<description>Web &#38; app MVC PHP framework</description>
	<lastBuildDate>Mon, 24 Nov 2025 21:51:00 +0000</lastBuildDate>
	<language>es</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.9.4</generator>

<image>
	<url>https://kumbiaphp.com/blog/wp-content/uploads/2016/01/250-150x150.png</url>
	<title>KumbiaPHP Framework PHP en español</title>
	<link>https://kumbiaphp.com/blog/</link>
	<width>32</width>
	<height>32</height>
</image> 
<site xmlns="com-wordpress:feed-additions:1">123854898</site>	<item>
		<title>Chatbots inteligentes en PHP con KumbiaPHP</title>
		<link>https://kumbiaphp.com/blog/2025/11/07/chatbots-inteligentes-en-php-con-kumbiaphp/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=chatbots-inteligentes-en-php-con-kumbiaphp</link>
					<comments>https://kumbiaphp.com/blog/2025/11/07/chatbots-inteligentes-en-php-con-kumbiaphp/#respond</comments>
		
		<dc:creator><![CDATA[HenryStivens]]></dc:creator>
		<pubDate>Fri, 07 Nov 2025 06:00:00 +0000</pubDate>
				<category><![CDATA[AI]]></category>
		<category><![CDATA[Tutoriales y screencast]]></category>
		<category><![CDATA[ejemplos]]></category>
		<guid isPermaLink="false">https://kumbiaphp.com/blog/?p=2975</guid>

					<description><![CDATA[<p>¿Qué es un chatbot inteligente? Un chatbot con PHP es un asistente virtual que usa inteligencia artificial para simular&#8230;</p>
<p>La entrada <a href="https://kumbiaphp.com/blog/2025/11/07/chatbots-inteligentes-en-php-con-kumbiaphp/">Chatbots inteligentes en PHP con KumbiaPHP</a> se publicó primero en <a href="https://kumbiaphp.com/blog">KumbiaPHP Framework PHP en español</a>.</p>
]]></description>
										<content:encoded><![CDATA[<p style="text-align: center;"><iframe title="YouTube video player" src="https://www.youtube.com/embed/ksijcOJSRAY?si=EPYBZNdJ6_KcJo0U" width="560" height="315" frameborder="0" allowfullscreen="allowfullscreen"></iframe></p>

<h2>¿Qué es un chatbot inteligente?</h2>
<p>Un chatbot con <a href="https://kumbiaphp.com/blog/category/php/">PHP</a> es un asistente virtual que usa inteligencia artificial para simular una conversación natural con usuarios, realizando tareas como responder preguntas, agendar citas, brindar soporte técnico y más. Implementar un chatbot inteligente utilizando PHP puede potenciar significativamente tu aplicación web.</p>
<p data-pm-slice="1 1 []">Veremos paso a paso cómo configurar las dependencias, conectar con el modelo GPT-4 y construir una interfaz simple que permita interactuar con el asistente directamente desde tu aplicación web.</p>
<h2>Herramientas recomendadas para crear chatbots con PHP</h2>
<ul data-spread="false">
<li>
<p><a href="https://openai.com/es-ES/api/"><strong>OpenAI API</strong></a>: Facilita el acceso a modelos avanzados como GPT-4 para procesamiento de lenguaje natural y es ideal para construir un chatbot con PHP.</p>
</li>
<li>
<p><a href="https://dialogflow.cloud.google.com/"><strong>Dialogflow</strong></a>: Servicio gestionado de Google que simplifica la creación de interfaces conversacionales y puede integrarse fácilmente como chatbot con PHP.</p>
</li>
<li>
<p><a href="https://rasa.com/"><strong>Rasa</strong></a>: Alternativa open source para chatbots personalizados y con mayor control, perfecta para crear un chatbot con PHP.</p>
</li>
</ul>
<h2>Creando un chatbot con PHP y KumbiaPHP usando la API de OpenAI</h2>
<h4>Paso 1: Instalar dependencias</h4>
<p>Usa Composer para instalar la librería oficial de OpenAI para tu chatbot con PHP (<a href="https://packagist.org/packages/openai-php/client">Packagist de</a><br /><a href="https://packagist.org/packages/openai-php/client">OpenAI PHP</a>):</p>


<pre class="wp-block-code language-bash"><code class="" data-line="">composer require openai-php/client</code></pre>



<span id="more-2975"></span>


<h4 data-pm-slice="1 1 []">Paso 2: Configuración específica para OpenAI</h4>
<p>Crea un archivo específico para la configuración en <em>config/openai.php</em> para tu chatbot con PHP:</p>


<pre class="wp-block-code language-php"><code class="" data-line="">&lt;?php

return &#091;
    &#039;api_key&#039; =&gt; &#039;TU_API_KEY&#039;,
    &#039;model&#039; =&gt; &#039;gpt-4-turbo&#039;,
    &#039;systemPrompt&#039; =&gt; 
        &#039;Eres un asistente útil. Te llamas Kumbita y amas Kumbiaphp&#039;,
];</code></pre>


<h4 data-pm-slice="1 1 []">Paso 3: Crear modelo para lógica de OpenAI</h4>
<p>Crea el archivo <em>app/models/open_ai_model.php</em>, esencial para desarrollar un chatbot con PHP:</p>


<pre class="wp-block-code language-php"><code class="" data-line="">&lt;?php

use \OpenAI\Client;

/**
 * OpenAI Service Model
 */
class OpenAiModel
{
    /**
     * @var OpenAiModel|null Instancia única de la clase
     */
    private static ?OpenAiModel $instance;

    /**
     * @var Client El cliente OpenAI
     */
    private Client $client;

    /**
     * @var array Configuración de OpenAI
     */
    private array $config;

    /**
     * Constructor para otras config
     *
     * @param array Configuración (opcional)
     */
    public function __construct(?array $config = null)
    {
        $this-&gt;config = $config ?? Config::read(&#039;openai&#039;);
        $this-&gt;client = OpenAI::client($this-&gt;config&#091;&#039;api_key&#039;]);
    }

    /**
     * Obtiene la instancia única del servicio
     *
     * @param array Configuración (opcional)
     * @return OpenAiModel
     */
    public static function getInstance(?array $config = null): self
    {
        return self::$instance ??= new self($config);
    }

    /**
     * Obtiene el cliente OpenAI
     * 
     * @return Client
     */
    public function getClient(): Client
    {
        return $this-&gt;client;
    }

    /**
     * Envía un mensaje a OpenAI y recibe la respuesta
     * 
     * @param string $message El mensaje del usuario
     * @param string $systemPrompt El prompt del sistema (opcional)
     *
     * @return string La respuesta del modelo
     */
    public function sendMessage(string $message, ?string $systemPrompt = null): string
    {
        $response = $this-&gt;client-&gt;chat()-&gt;create(&#091;
            &#039;model&#039; =&gt; $this-&gt;config&#091;&#039;model&#039;],
            &#039;messages&#039; =&gt; &#091;
                &#091;
                  &#039;role&#039; =&gt; &#039;system&#039;,
                  &#039;content&#039; =&gt; $systemPrompt ?? $this-&gt;config&#091;&#039;systemPrompt&#039;]
                ],
                &#091;
                  &#039;role&#039; =&gt; &#039;user&#039;,
                  &#039;content&#039; =&gt; $message
                ],
            ],
        ]);

        return $response-&gt;choices&#091;0]-&gt;message-&gt;content;
    }
}</code></pre>


<h4 data-pm-slice="1 1 []">Paso 4: Crear controlador Chatbot en KumbiaPHP</h4>


<pre class="wp-block-code language-php"><code class="" data-line="">&lt;?php

class ChatbotController extends AppController
{
    /**
     * Muestra el chatbot
     */
    public function index()
    {
    }

    /**
     * Endpoint para manejar mensajes del chatbot
     */
    public function message()
    {
        View::select(null, &#039;json&#039;);

        $message = Input::post(&#039;message&#039;);

        $this-&gt;data = match ($message) {
            null, &#039;&#039; =&gt; &#091;],
            default =&gt;  &#091;&#039;reply&#039; =&gt; OpenAiModel::getInstance()-&gt;sendMessage($message)],
        };
    }
}
</code></pre>


<h4 data-pm-slice="1 1 []">Paso 5: Crear la vista del chatbot en KumbiaPHP</h4>
<p>Crea la vista <em>index.phtml</em> en <em>app/views/chatbot/</em> para interactuar fácilmente con tu chatbot con PHP:</p>


<pre class="wp-block-code language-php"><code class="" data-line="">&lt;section id=&quot;aibot&quot;&gt;
    &lt;h1&gt;Chatbot Inteligente con PHP y KumbiaPHP&lt;/h1&gt;

    &lt;div id=&quot;chatResponse&quot;&gt;
        &lt;p&gt;
            &lt;b&gt;Kumbita:&lt;/b&gt; Hola, me llamo Kumbita. ¿Qué quieres saber hoy?
        &lt;/p&gt;
    &lt;/div&gt;

    &lt;?= Form::open(&#039;&#039;, &#039;POST&#039;, &#039;id=&quot;chatbot&quot;&#039;) ?&gt;
    &lt;?= Form::text(&#039;message&#039;, &#039;placeholder=&quot;Escribe tu pregunta&quot; autofocus&#039;) ?&gt;
    &lt;?= Form::submit(&#039;Enviar&#039;, &#039;class=&quot;btn btn-primary&quot;&#039;) ?&gt;
    &lt;?= Form::close() ?&gt;
&lt;/section&gt;

&lt;script&gt;
    document.getElementById(&quot;chatbot&quot;).addEventListener(&quot;submit&quot;,
        function(event) {
            event.preventDefault();
            sendMessage();
        });

    const messageEl = document.getElementById(&#039;message&#039;);
    const chatResponse = document.getElementById(&#039;chatResponse&#039;);
    const btnSubmit = document.querySelector(&#039;#chatbot &#091;type=&quot;submit&quot;]&#039;);
    const speech = &#039;speechSynthesis&#039; in window ? new SpeechSynthesisUtterance() : null;
    const apiError = &quot;Lo siento, parece que hay un error al conectar a la API&quot;;

    speak(&quot;Hola, me llamo Kumbita. ¿Qué quieres saber hoy?&quot;, &quot;es&quot;);

    function sendMessage() {
        const message = messageEl.value;
        if(message.trim() === &#039;&#039;) return;
        btnSubmit.disabled = true;
        messageEl.disabled = true;
        chatResponse.innerHTML += `&lt;p&gt;&lt;b&gt;Tu:&lt;/b&gt; ${message}&lt;/p&gt;&lt;div id=&quot;loading&quot;&gt;&lt;/div&gt;`;
        chatResponse.scrollTop = chatResponse.scrollHeight;

        fetch(&#039;/chatbot/message&#039;, {
                method: &#039;POST&#039;,
                headers: {
                    &#039;Content-Type&#039;: &#039;application/x-www-form-urlencoded&#039;,
                    &#039;Accept&#039;: &#039;application/json&#039;
                },
                body: &#039;message=&#039; + encodeURIComponent(message)
            })
            .then(response =&gt; response.json())
            .then(data =&gt; {
                response(data.reply ?? &quot;&quot;);
            })
            .catch(error =&gt; {
                console.log(error);
                response(apiError);
            })
            .finally(() =&gt; {
                btnSubmit.disabled = false;
                messageEl.disabled = false;
                messageEl.value = &#039;&#039;;
                messageEl.focus();
            });
    }

    function response(message) {
        speak(message);
        document.getElementById(&#039;loading&#039;).remove();
        chatResponse.innerHTML += `&lt;p&gt;&lt;b&gt;Kumbita:&lt;/b&gt; ${message}&lt;/p&gt;`;
        chatResponse.scrollTop = chatResponse.scrollHeight;
    }

    function speak(text, lang = navigator.language) {
        if(!speech) return;
        speech.lang = lang
        speech.text = text
        window.speechSynthesis.speak(speech)
    }
&lt;/script&gt;

&lt;style&gt;
    #aibot {
        max-width: 500px;
        margin: 0 auto;

        &amp; h1 {
            text-align: center;
        }

        &amp; #chatbot {
            display: flex;
            margin-top: 1em;
        }

        &amp; #message {
            flex: 1;
            border-radius: 2rem 0 0 2rem;
            padding: 0.5em 1em;
            box-shadow: none;

            &amp;:focus {
                outline: none;
            }
        }

        &amp; &#091;type=&quot;submit&quot;] {
            flex: 0;
            border-radius: 0 2rem 2rem 0;
            box-shadow: none;
            
            &amp;:disabled {
                opacity: 0.5;
            }
        }

        &amp; #chatResponse {
            margin: 20px auto 0;
            min-height: 60px;
            max-height: 400px;
            background: #f5f5f5;
            border-radius: 6px;
            padding: 1em;
            box-shadow: 1px 1px 5px #eee;
            overflow-y: auto;
            display: flex;
            flex-direction: column;

            &amp; p {
                color: #333;
            }
        }
    }
    #loading {
        width: 12px;
        height: 12px;
        border-radius: 50%;
        display: block;
        margin:15px auto;
        position: relative;
        color: #9ab8ef;
        box-sizing: border-box;
        animation: animloader 1s linear infinite alternate;
    }

    @keyframes animloader {
        0% {box-shadow: -38px -6px, -14px 6px,  14px -6px;}
        33% {box-shadow: -38px 6px, -14px -6px,  14px 6px;}
        66% {box-shadow: -38px -6px, -14px 6px, 14px -6px;}
        100% {box-shadow: -38px 6px, -14px -6px, 14px 6px;}
    }
&lt;/style&gt;
</code></pre>



<figure class="wp-block-image size-large"><a href="https://kumbiaphp.com/blog/wp-content/uploads/2025/11/kumbiaphp-chatbot-openai.jpg"><img fetchpriority="high" decoding="async" width="1024" height="576" src="https://kumbiaphp.com/blog/wp-content/uploads/2025/11/kumbiaphp-chatbot-openai-1024x576.jpg" alt="Chatbot inteligente con PHP Y KumbiaPHP" class="wp-image-2989" srcset="https://kumbiaphp.com/blog/wp-content/uploads/2025/11/kumbiaphp-chatbot-openai-1024x576.jpg 1024w, https://kumbiaphp.com/blog/wp-content/uploads/2025/11/kumbiaphp-chatbot-openai-300x169.jpg 300w, https://kumbiaphp.com/blog/wp-content/uploads/2025/11/kumbiaphp-chatbot-openai-768x432.jpg 768w, https://kumbiaphp.com/blog/wp-content/uploads/2025/11/kumbiaphp-chatbot-openai-1536x864.jpg 1536w, https://kumbiaphp.com/blog/wp-content/uploads/2025/11/kumbiaphp-chatbot-openai-940x529.jpg 940w, https://kumbiaphp.com/blog/wp-content/uploads/2025/11/kumbiaphp-chatbot-openai.jpg 1920w" sizes="(max-width: 1024px) 100vw, 1024px" /></a></figure>


<h3 data-pm-slice="1 1 []">Ventajas de usar chatbots en aplicaciones PHP</h3>
<ul data-spread="false">
<li>
<p>Disponibilidad 24/7.</p>
</li>
<li>
<p>Respuestas inmediatas y personalizadas.</p>
</li>
<li>
<p>Optimización de recursos humanos y reducción de costos operativos.</p>
</li>
</ul>
<p>Este ejemplo constituye una <strong>base sólida</strong> para comprender cómo integrar inteligencia artificial en tus proyectos PHP con KumbiaPHP. A partir de aquí, puedes ampliarlo añadiendo <strong>manejo de historial de conversación</strong>, <strong>personalización de prompts del sistema</strong>, <strong>validaciones adicionales de entrada</strong>, o incluso <strong>mecanismos de seguridad</strong> para evitar abusos en el endpoint.</p>
<p>Al finalizar esta guía, tendrás un chatbot completamente funcional listo para integrarse en cualquier proyecto desarrollado con KumbiaPHP. Anímate a probarlo, experimentar con sus respuestas y descubrir el potencial de combinar la sencillez de PHP con la potencia de la inteligencia artificial. Si te ha resultado útil, <strong>comparte este artículo</strong> o deja tus comentarios en el blog para seguir mejorando juntos.</p>


<h2 class="wp-block-heading">Agradecimientos</h2>



<p class="wp-block-paragraph">Agradecemos especialmente a @joanhey por tomarse el tiempo de revisar y mejorar el código de ejemplo, aportando sugerencias valiosas que ayudaron a hacerlo más claro y funcional para la comunidad de desarrolladores de KumbiaPHP.</p>
<p>La entrada <a href="https://kumbiaphp.com/blog/2025/11/07/chatbots-inteligentes-en-php-con-kumbiaphp/">Chatbots inteligentes en PHP con KumbiaPHP</a> se publicó primero en <a href="https://kumbiaphp.com/blog">KumbiaPHP Framework PHP en español</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://kumbiaphp.com/blog/2025/11/07/chatbots-inteligentes-en-php-con-kumbiaphp/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2975</post-id>	</item>
		<item>
		<title>Novedades del Manual de KumbiaPHP — noviembre 2025</title>
		<link>https://kumbiaphp.com/blog/2025/11/03/novedades-del-manual-de-kumbiaphp-noviembre-2025/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=novedades-del-manual-de-kumbiaphp-noviembre-2025</link>
					<comments>https://kumbiaphp.com/blog/2025/11/03/novedades-del-manual-de-kumbiaphp-noviembre-2025/#respond</comments>
		
		<dc:creator><![CDATA[HenryStivens]]></dc:creator>
		<pubDate>Mon, 03 Nov 2025 12:25:00 +0000</pubDate>
				<category><![CDATA[Documentación]]></category>
		<category><![CDATA[MVC framework]]></category>
		<guid isPermaLink="false">https://kumbiaphp.com/blog/?p=2961</guid>

					<description><![CDATA[<p>Ya están publicados nuevos contenidos y mejoras en la documentación: guías de instalación en Apache y Nginx (en inglés),&#8230;</p>
<p>La entrada <a href="https://kumbiaphp.com/blog/2025/11/03/novedades-del-manual-de-kumbiaphp-noviembre-2025/">Novedades del Manual de KumbiaPHP — noviembre 2025</a> se publicó primero en <a href="https://kumbiaphp.com/blog">KumbiaPHP Framework PHP en español</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">Ya están publicados nuevos contenidos y mejoras en la documentación: guías de instalación en <strong>Apache y Nginx (en inglés)</strong>, una <strong>guía “Primera App”</strong> en español totalmente revisada, <strong>instrucciones para instalar con Composer</strong> y una <strong>sección de Controladores</strong> clarificada y con imágenes nuevas. Todo esto alineado con <strong>KumbiaPHP 1.2 optimizado para PHP 8</strong>. Consulta el repo del manual para ver los cambios completos. (<a href="https://github.com/KumbiaPHP/Documentation">GitHub</a>)</p>



<h2 class="wp-block-heading">1) Nuevas guías: instalación en Apache y Nginx (en inglés)</h2>



<p class="wp-block-paragraph">Publicamos instrucciones claras para servir aplicaciones KumbiaPHP detrás de <strong>Apache</strong> (VirtualHosts) y <strong>Nginx</strong> (server blocks), destacando los puntos clave: usar <em>public/</em> como <em>document root</em> y habilitar las reglas de reescritura para el <em>front controller</em>. Estas guías facilitan el despliegue en entornos modernos sin dependencias innecesarias. <a href="https://github.com/KumbiaPHP/Documentation/tree/master/en" target="_blank" rel="noreferrer noopener">GitHub</a></p>



<figure class="wp-block-image size-full is-style-default"><a href="https://kumbiaphp.com/blog/wp-content/uploads/2025/11/kumbiaphp-virtual-host-example.jpg"><img decoding="async" width="749" height="342" src="https://kumbiaphp.com/blog/wp-content/uploads/2025/11/kumbiaphp-virtual-host-example.jpg" alt="Apache apuntando a public/ con URLs limpias." class="wp-image-2963" srcset="https://kumbiaphp.com/blog/wp-content/uploads/2025/11/kumbiaphp-virtual-host-example.jpg 749w, https://kumbiaphp.com/blog/wp-content/uploads/2025/11/kumbiaphp-virtual-host-example-300x137.jpg 300w" sizes="(max-width: 749px) 100vw, 749px" /></a></figure>



<span id="more-2961"></span>



<figure class="wp-block-image size-full"><a href="https://kumbiaphp.com/blog/wp-content/uploads/2025/11/kumbiaphp-nginx-example.jpg"><img loading="lazy" decoding="async" width="769" height="494" src="https://kumbiaphp.com/blog/wp-content/uploads/2025/11/kumbiaphp-nginx-example.jpg" alt="Nginx + PHP-FPM con public/ como raíz del sitio." class="wp-image-2964" srcset="https://kumbiaphp.com/blog/wp-content/uploads/2025/11/kumbiaphp-nginx-example.jpg 769w, https://kumbiaphp.com/blog/wp-content/uploads/2025/11/kumbiaphp-nginx-example-300x193.jpg 300w" sizes="auto, (max-width: 769px) 100vw, 769px" /></a></figure>



<p class="wp-block-paragraph"><strong>Qué encontrarás:</strong></p>



<ul class="wp-block-list">
<li>Estructura mínima y <em>document root</em> correcto (public/).</li>



<li>Directrices de reescritura para URLs limpias (<em>pretty URLs</em>).</li>



<li>Notas rápidas para PHP-FPM (Nginx) y módulos en Apache.</li>
</ul>



<h2 class="wp-block-heading">2) “Primera App” — más clara y didáctica</h2>



<p class="wp-block-paragraph">La guía <strong>Primera App</strong> fue reescrita con foco en personas que inician con MVC:</p>



<p class="wp-block-paragraph"><strong>a.</strong> Se <strong>aclaró la arquitectura MVC y el manejo de URLs</strong>, explicando cómo el <em>front controller</em> enruta /<em>controlador/acción/param</em> hacia tu lógica.<br><strong>b.</strong> <strong>Se actualizaron los ejemplos de controladores y vistas</strong>, con código más legible y ordenado.</p>



<figure class="wp-block-image size-full"><a href="https://kumbiaphp.com/blog/wp-content/uploads/2025/11/successful-installation.jpg"><img loading="lazy" decoding="async" width="960" height="540" src="https://kumbiaphp.com/blog/wp-content/uploads/2025/11/successful-installation.jpg" alt="Primera ejecución y render de vista básica." class="wp-image-2966" srcset="https://kumbiaphp.com/blog/wp-content/uploads/2025/11/successful-installation.jpg 960w, https://kumbiaphp.com/blog/wp-content/uploads/2025/11/successful-installation-300x169.jpg 300w, https://kumbiaphp.com/blog/wp-content/uploads/2025/11/successful-installation-768x432.jpg 768w, https://kumbiaphp.com/blog/wp-content/uploads/2025/11/successful-installation-940x529.jpg 940w" sizes="auto, (max-width: 960px) 100vw, 960px" /></a></figure>



<p class="wp-block-paragraph"><strong>c.</strong> <strong>Se mejoraron los títulos y subtítulos</strong> para escanear mejor el contenido.<br><strong>d.</strong> <strong>Se reemplazaron capturas de pantalla</strong>, haciendo más evidente cada paso (crear controlador, renderizar vista, pasar variables).</p>



<h2 class="wp-block-heading">3) Instalación con Composer (nuevo apartado)</h2>



<p class="wp-block-paragraph">Ahora el manual incluye un flujo directo para iniciar proyectos con <strong>Composer</strong>:</p>



<p class="wp-block-paragraph"><strong>Requisitos mínimos:</strong> PHP 8.x recomendado.<br><strong>Pasos típicos:</strong></p>



<p class="wp-block-paragraph"><strong>1) Crear un nuevo proyecto base de KumbiaPHP</strong><br>composer create-project kumbia/framework myapp<br><strong>2) Entrar al proyecto</strong><br>cd myapp/default/app<br><strong>3) Iniciar servidor de desarrollo de PHP apuntando a public/</strong><br>./bin/phpserver</p>



<figure class="wp-block-image size-full"><a href="https://kumbiaphp.com/blog/wp-content/uploads/2025/11/kumbiaphp-composer-example.jpg"><img loading="lazy" decoding="async" width="769" height="494" src="https://kumbiaphp.com/blog/wp-content/uploads/2025/11/kumbiaphp-composer-example.jpg" alt="Proyecto KumbiaPHP generado con Composer en segundos.”" class="wp-image-2967" srcset="https://kumbiaphp.com/blog/wp-content/uploads/2025/11/kumbiaphp-composer-example.jpg 769w, https://kumbiaphp.com/blog/wp-content/uploads/2025/11/kumbiaphp-composer-example-300x193.jpg 300w" sizes="auto, (max-width: 769px) 100vw, 769px" /></a></figure>



<p class="wp-block-paragraph">El paquete <strong>framework</strong> es el esqueleto básico para comenzar: genera la estructura y te deja listo para desarrollar. Si eres nuevo en Composer, la sección <a href="https://github.com/KumbiaPHP/Documentation/blob/master/es/to-install.md#instalaci%C3%B3n-con-composer">Instalación con Composer</a> te guiarán sobre cómo funciona <code class="" data-line="">composer.json</code> y los comandos principales.</p>



<h2 class="wp-block-heading">4) Controladores: contenido revisado + nuevas imágenes</h2>



<p class="wp-block-paragraph">La sección de <strong>Controladores</strong> se reordenó para mejorar la lectura y cubrir escenarios reales:</p>



<ul class="wp-block-list">
<li><strong>Validación de parámetros:</strong> número de parámetros, pasar valores a la vista, convenciones de nombrado, acciones y filtros.</li>



<li><strong>Controladores dinámicos:</strong> cuándo conviene y cómo mantenerlos legibles.</li>
</ul>



<h2 class="wp-block-heading">Enlaces rápidos</h2>



<ul class="wp-block-list">
<li><strong>Manual (repo):</strong> documentación central y carpetas es/ y en/. (<a href="https://github.com/KumbiaPHP/Documentation">GitHub</a>)</li>



<li><strong>Paquete framework en Packagist:</strong> referencias y enlaces al manual. (<a href="https://packagist.org/packages/kumbia/framework?utm_source=chatgpt.com">Packagist</a>)</li>
</ul>



<h2 class="wp-block-heading">Gracias a la comunidad <img src="https://s.w.org/images/core/emoji/17.0.2/72x72/1f64c.png" alt="🙌" class="wp-smiley" style="height: 1em; max-height: 1em;" /></h2>



<p class="wp-block-paragraph">Estas mejoras nacen de <em>pull requests</em> recientes y la colaboración constante de la comunidad. Si quieres proponer cambios, abre un PR en el repo del manual o únete al Slack para coordinar traducciones/imágenes adicionales. ¡Seguimos puliendo el contenido para que empezar con <strong>KumbiaPHP 1.2 (PHP 8)</strong> sea cada vez más fácil!</p>



<p class="wp-block-paragraph"></p>
<p>La entrada <a href="https://kumbiaphp.com/blog/2025/11/03/novedades-del-manual-de-kumbiaphp-noviembre-2025/">Novedades del Manual de KumbiaPHP — noviembre 2025</a> se publicó primero en <a href="https://kumbiaphp.com/blog">KumbiaPHP Framework PHP en español</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://kumbiaphp.com/blog/2025/11/03/novedades-del-manual-de-kumbiaphp-noviembre-2025/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2961</post-id>	</item>
		<item>
		<title>Buscador avanzado de texto completo para KumbiaPHP con Meilisearch</title>
		<link>https://kumbiaphp.com/blog/2025/04/19/buscador-avanzado-texto-completo-kumbiaphp-meilisearch/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=buscador-avanzado-texto-completo-kumbiaphp-meilisearch</link>
					<comments>https://kumbiaphp.com/blog/2025/04/19/buscador-avanzado-texto-completo-kumbiaphp-meilisearch/#respond</comments>
		
		<dc:creator><![CDATA[HenryStivens]]></dc:creator>
		<pubDate>Sat, 19 Apr 2025 08:00:00 +0000</pubDate>
				<category><![CDATA[AI]]></category>
		<category><![CDATA[Tutoriales y screencast]]></category>
		<category><![CDATA[buscador]]></category>
		<category><![CDATA[ejemplos]]></category>
		<guid isPermaLink="false">https://kumbiaphp.com/blog/?p=2903</guid>

					<description><![CDATA[<p>La entrada <a href="https://kumbiaphp.com/blog/2025/04/19/buscador-avanzado-texto-completo-kumbiaphp-meilisearch/">Buscador avanzado de texto completo para KumbiaPHP con Meilisearch</a> se publicó primero en <a href="https://kumbiaphp.com/blog">KumbiaPHP Framework PHP en español</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<div style="text-align:center;"><iframe loading="lazy" width="560" height="315" src="https://www.youtube.com/embed/knyUp-Wleg4?si=b5TdpovBYkE4dCpm" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture; web-share" referrerpolicy="strict-origin-when-cross-origin" allowfullscreen></iframe></div>



<p class="" data-start="271" data-end="624">Si estás buscando implementar un <strong data-start="304" data-end="374">buscador avanzado de texto completo para KumbiaPHP con <a href="https://www.meilisearch.com/">Meilisearch</a></strong>, este artículo te mostrará cómo hacerlo de manera sencilla, efectiva y escalable. Descubre cómo aprovechar todo el potencial de Meilisearch en tus aplicaciones KumbiaPHP, ofreciendo a tus usuarios búsquedas rápidas y resultados altamente relevantes.</p>
<h2>¿Por qué utilizar un buscador avanzado de texto completo para KumbiaPHP con Meilisearch?</h2>
<p>Implementar un <strong data-start="739" data-end="809">buscador avanzado de texto completo para KumbiaPHP con Meilisearch</strong> permite llevar las capacidades de búsqueda de tus aplicaciones a otro nivel. Meilisearch es un motor de búsqueda rápido, potente y de fácil configuración, ideal para aplicaciones modernas que requieren búsquedas en tiempo real, autocompletado y manejo de grandes volúmenes de datos.<br data-start="1020" data-end="1023" />Además, gracias a sus capacidades de búsqueda semántica impulsada por inteligencia artificial, se pueden obtener resultados mucho más precisos incluso cuando las palabras de búsqueda no coinciden exactamente con los términos indexados.</p>
<h2>Requisitos</h2>
<p>Antes de comenzar a integrar un <strong data-start="2097" data-end="2167">buscador avanzado de texto completo para KumbiaPHP con Meilisearch</strong>, verifica que tu entorno cumpla con los siguientes requisitos básicos:</p>
<ul>
<li>
<p>Tener una aplicación funcionando con <strong><a href="https://kumbiaphp.com/blog/manuales-y-descargas/">KumbiaPHP 1.2</a> o superior</strong>.</p>
</li>
<li>
<p>Tener <strong><a href="_wp_link_placeholder" data-wplink-edit="true">PHP 8.0</a> o superior</strong>.</p>
</li>
<li>
<p>Tener acceso al servidor o contenedor donde correrá <strong>Meilisearch</strong>.</p>
</li>
<li>
<p>Instalar el cliente de Meilisearch para PHP con Composer:</p>
</li>
</ul>
<pre><code class="language-bash" data-line="">composer require meilisearch/meilisearch-php \
guzzlehttp/guzzle \
http-interop/http-factory-guzzle:^1.0</code></pre>
<ul>
<li>
<p>Instalar el nuevo ActiveRecord de KumbiaPHP si aún no lo tienes:</p>
</li>
</ul>
<pre><code class="language-bash" data-line="">composer require kumbia/activerecord
</code></pre>
<blockquote>
<p>Este nuevo ActiveRecord es un componente externo que puedes usar en cualquier proyecto PHP, y es requerido para que los modelos soporten los callbacks usados por el trait MeilisearchSearchable.</p>
</blockquote>
<h2 id="configuraci%C3%B3n-del-cliente-meilisearch-singleton" class="code-line" dir="auto" data-line="31">Configuración del Cliente Meilisearch</h2>
<p class="code-line" dir="auto" data-line="33">Crea el archivo <em>default/app/config/meilisearch.php</em> con la siguiente estructura:</p>



<span id="more-2903"></span>



<pre class="wp-block-code language-php"><code class="" data-line="">&lt;?php
/**
 * MeiliSearch configuration file.
 *
 * This file contains the configuration settings for connecting to MeiliSearch.
 */
return &#091;
    &#039;host&#039; =&gt; &#039;http://127.0.0.1:7700&#039;, // Change the host
    &#039;api_key&#039; =&gt; &#039;&#039;, // Change the key
];
</code></pre>



<h2 id="integrando-meilisearch-con-el-trait-meilisearchsearchabletrait" class="code-line" dir="auto" data-line="63">Trait MeilisearchSearchableTrait</h2>
<p class="code-line" dir="auto" data-line="65">Crea el archivo&nbsp;<em>default/app/libs/meilisearch_searchable_trait.php</em> con el siguiente código:</p>



<pre class="wp-block-code language-php"><code class="" data-line="">&lt;?php

use Meilisearch\Client;

/**
 * Trait MeilisearchSearchableTrait
 */
trait MeilisearchSearchableTrait
{
    /**
     * MeiliSearch client instance.
     */
    protected static ?Client $_meiliClient = null;

    /**
     * Retrieves the MeiliSearch client instance.
     */
    protected static function getMeiliClient(): Client
    {
        if (null !== self::$_meiliClient) {
            return self::$_meiliClient;
        }

        $config = \Config::read(&#039;meilisearch&#039;);
        if (!$config || !is_array($config)) {
            throw new \RuntimeException(&#039;MeiliSearch configuration not found in config file.&#039;);
        }
        $host   = $config&#091;&#039;host&#039;] ?? &#039;http://localhost:7700&#039;;
        $apiKey = $config&#091;&#039;api_key&#039;] ?? &#039;&#039;;

        return self::$_meiliClient = new Client($host, $apiKey);
    }

    /**
     * Returns the index name. By default it returns the table name provided by the model.
     */
    protected static function searchableAs(): string
    {
        return static::getTable();
    }

    /**
     * Converts the model instance to an array for indexing.
     */
    abstract protected function toSearchArray(): array;

    /**
     * Callback executed after a model is created.
     * The new record is automatically added to the MeiliSearch index.
     */
    protected function _afterCreate(): void
    {
        self::getMeiliClient()
            -&gt;index(static::searchableAs())
            -&gt;addDocuments(&#091;$this-&gt;toSearchArray()]);
    }

    /**
     * Callback executed after a model is updated.
     * The updated record is synchronized in the MeiliSearch index.
     */
    protected function _afterUpdate(): void
    {
        self::getMeiliClient()
            -&gt;index(static::searchableAs())
            -&gt;updateDocuments(&#091;$this-&gt;toSearchArray()]);
    }

    /**
     * Deletes a record and synchronizes the deletion with the MeiliSearch index.
     */
    public static function delete($pk): bool
    {
        $deleted = parent::delete($pk);

        if ($deleted) {
            self::getMeiliClient()
                -&gt;index(static::searchableAs())
                -&gt;deleteDocument($pk);
        }

        return $deleted;
    }

    /**
     * Performs a search query on the MeiliSearch index.
     */
    public static function search(string $query, array $options = &#091;]): array
    {
        $results = self::getMeiliClient()
            -&gt;index(static::searchableAs())
            -&gt;search($query, $options);

        return $results-&gt;getHits();
    }

    /**
     * Bulk-imports existing records into the MeiliSearch index.
     */
    public static function importToMeilisearch(int $chunkSize = 500): void
    {
        $offset = 0;

        do {
            $records = static::filter(&quot;LIMIT $chunkSize OFFSET $offset&quot;);
            $data    = &#091;];

            foreach ($records as $record) {
                $data&#091;] = $record-&gt;toSearchArray();
            }

            if (!empty($data)) {
                self::getMeiliClient()
                    -&gt;index(static::searchableAs())
                    -&gt;addDocuments($data);
            }

            $offset += $chunkSize;
        } while (count($records) === $chunkSize);
    }
}
</code></pre>



<h2>Ventajas del Trait MeilisearchSearchable</h2>
<ul>
<li>
<p><strong>Integración simple</strong>: Reutiliza fácilmente la funcionalidad en múltiples modelos.</p>
</li>
<li>
<p><strong>Automatización</strong>: Mantiene sincronizados automáticamente tus modelos con el índice de búsqueda.</p>
</li>
<li>
<p><strong>Flexibilidad</strong>: Puedes personalizar fácilmente el comportamiento de búsqueda por cada modelo.</p>
</li>
<li><strong>Inteligencia Artificial:</strong> Soporte para búsqueda semántica mediante integración con IA (OpenAI u otros proveedores).</li>
</ul>
<h2 class="" data-start="3331" data-end="3432">Cómo utilizar en la práctica un buscador avanzado de texto completo para KumbiaPHP con Meilisearch</h2>



<h3 data-pm-slice="1 1 []">Paso 1: Implementación en Modelos</h3>
<p>A continuación, integra el trait en tus modelos que extiendan de LiteRecord:</p>
<h4>Ejemplo con Modelo Product</h4>



<pre class="wp-block-code language-php"><code class="" data-line="">&lt;?php

use Kumbia\ActiveRecord\LiteRecord;

class Product extends LiteRecord
{
    use MeilisearchSearchableTrait;

    protected static $table = &#039;products&#039;;

    protected function toSearchArray(): array
    {
        return &#091;
            &#039;id&#039; =&gt; $this-&gt;id,
            &#039;name&#039; =&gt; $this-&gt;name,
            &#039;description&#039; =&gt; $this-&gt;description,
            &#039;price&#039; =&gt; $this-&gt;price,
        ];
    }
}</code></pre>



<h4 data-pm-slice="1 1 []">Ejemplo con Modelo Article</h4>



<pre class="wp-block-code language-php"><code class="" data-line="">&lt;?php

use Kumbia\ActiveRecord\LiteRecord;

class Article extends LiteRecord
{
    use MeilisearchSearchableTrait;

    protected static $table = &#039;articles&#039;;

    protected function toSearchArray(): array
    {
        return &#091;
            &#039;id&#039; =&gt; $this-&gt;id,
            &#039;title&#039; =&gt; $this-&gt;title,
            &#039;content&#039; =&gt; $this-&gt;content,
            &#039;author&#039; =&gt; $this-&gt;author,
        ];
    }
}</code></pre>



<p data-pm-slice="1 1 []">Una vez implementado el trait en tus modelos, realizar búsquedas será simple y eficaz. Estos ejemplos prácticos ilustran claramente cómo aprovechar tu nuevo <strong data-start="3591" data-end="3661">buscador avanzado de texto completo para KumbiaPHP con Meilisearch</strong>.</p>
<h3 data-pm-slice="1 1 []">Paso 2: Realizar búsquedas fácilmente</h3>
<p>Ahora puedes realizar búsquedas en tus modelos:</p>



<pre class="wp-block-code language-php"><code class="" data-line="">// Buscar productos
$products = Product::search(&#039;zapatos deportivos&#039;, &#091;&#039;limit&#039; =&gt; 10]);

// Buscar artículos
$articles = Article::search(&#039;tecnología&#039;, &#091;&#039;limit&#039; =&gt; 5]);</code></pre>



<h3 data-pm-slice="1 1 []">Paso 3: Importar datos existentes</h3>
<p>Si ya tienes datos almacenados en tu base de datos, puedes importarlos fácilmente:</p>



<pre class="wp-block-code language-php"><code class="" data-line="">Product::importToMeilisearch();
Article::importToMeilisearch();</code></pre>



<h2 data-pm-slice="1 1 []">Ejemplo de Mielisearch con Controlador y Vista en KumbiaPHP</h2>
<h3>Paso 1: Crea el controlador</h3>
<p>Controlador: <em>app/controllers/products_controller.php</em></p>



<pre class="wp-block-code language-php"><code class="" data-line="">class ProductsController extends AppController
{
    public function search()
    {
        if (Input::hasPost(&#039;query&#039;)) {
            $this-&gt;results = Product::search(Input::post(&#039;query&#039;));
        }
    }
}</code></pre>



<h3 data-pm-slice="1 1 []">Paso 2: Crea la vista</h3>
<p data-pm-slice="1 1 []">Vista: <em>app/views/products/search.phtml</em></p>



<pre class="wp-block-code language-php"><code class="" data-line="">&lt;h1&gt;Buscar productos&lt;/h1&gt;

&lt;?php View::content(); ?&gt;

&lt;?= Form::open(); ?&gt;
    &lt;?= Form::text(&#039;query&#039;, &#039;placeholder=&quot;Buscar...&quot;&#039;) ?&gt;
    &lt;?= Form::submit(&#039;Buscar&#039;) ?&gt;
&lt;?= Form::close(); ?&gt;

&lt;?php if (empty($results) &amp;&amp; Input::post(&#039;query&#039;)): ?&gt;
    &lt;p&gt;No se encontraron resultados.&lt;/p&gt;
    &lt;?php return 1 ?&gt;
&lt;?php endif; ?&gt;

&lt;h2&gt;Resultados&lt;/h2&gt;
&lt;ul&gt;
    &lt;?php foreach ($results as $product): ?&gt;
        &lt;li&gt;
            &lt;strong&gt;&lt;?= h($product&#091;&#039;name&#039;]) ?&gt;&lt;/strong&gt;&lt;br&gt;
            &lt;?= h($product&#091;&#039;description&#039;]) ?&gt;&lt;br&gt;
            Precio: $&lt;?= h($product&#091;&#039;price&#039;]) ?&gt;
        &lt;/li&gt;
    &lt;?php endforeach; ?&gt;
&lt;/ul&gt;
</code></pre>



<p data-pm-slice="1 1 []">La combinación de KumbiaPHP con Meilisearch a través del trait MeilisearchSearchable te permite ofrecer una experiencia superior en búsquedas a tus usuarios. Con la posibilidad de usar IA para búsquedas semánticas, la calidad de los resultados se eleva aún más. La integración es simple, escalable y potente, haciendo que valga la pena el esfuerzo inicial.</p>
<p>¡Prueba esta integración y lleva tus búsquedas al siguiente nivel con KumbiaPHP y Meilisearch!</p>
<p>La entrada <a href="https://kumbiaphp.com/blog/2025/04/19/buscador-avanzado-texto-completo-kumbiaphp-meilisearch/">Buscador avanzado de texto completo para KumbiaPHP con Meilisearch</a> se publicó primero en <a href="https://kumbiaphp.com/blog">KumbiaPHP Framework PHP en español</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://kumbiaphp.com/blog/2025/04/19/buscador-avanzado-texto-completo-kumbiaphp-meilisearch/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2903</post-id>	</item>
		<item>
		<title>Optimizando la Renderización Condicional en Vistas de KumbiaPHP con return 1;</title>
		<link>https://kumbiaphp.com/blog/2024/10/14/optimizando-la-renderizacion-condicional-en-vistas-de-kumbiaphp-con-return-1/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=optimizando-la-renderizacion-condicional-en-vistas-de-kumbiaphp-con-return-1</link>
					<comments>https://kumbiaphp.com/blog/2024/10/14/optimizando-la-renderizacion-condicional-en-vistas-de-kumbiaphp-con-return-1/#comments</comments>
		
		<dc:creator><![CDATA[HenryStivens]]></dc:creator>
		<pubDate>Mon, 14 Oct 2024 16:52:23 +0000</pubDate>
				<category><![CDATA[Documentación]]></category>
		<category><![CDATA[PHP]]></category>
		<category><![CDATA[ejemplos]]></category>
		<category><![CDATA[vistas]]></category>
		<guid isPermaLink="false">https://kumbiaphp.com/blog/?p=2823</guid>

					<description><![CDATA[<p>Aprende a optimizar la renderización condicional en vistas de KumbiaPHP usando return 1; para escribir código más limpio y eficiente sin bloques if-else innecesarios.</p>
<p>La entrada <a href="https://kumbiaphp.com/blog/2024/10/14/optimizando-la-renderizacion-condicional-en-vistas-de-kumbiaphp-con-return-1/">Optimizando la Renderización Condicional en Vistas de KumbiaPHP con return 1;</a> se publicó primero en <a href="https://kumbiaphp.com/blog">KumbiaPHP Framework PHP en español</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p class="wp-block-paragraph">En el desarrollo web, especialmente al trabajar con motores de plantillas o frameworks MVC como <a href="https://kumbiaphp.com/blog/manuales-y-descargas/">KumbiaPHP</a>, es común <a href="https://github.com/KumbiaPHP/Documentation/blob/master/es/view.md">renderizar</a> condicionalmente partes de una vista basándose en la disponibilidad de datos. Tradicionalmente, los desarrolladores utilizan sentencias <em>if-else</em> para controlar el flujo de renderización de la vista. Sin embargo, el uso excesivo de bloques <em>if-else</em> puede desordenar tu código y dificultar su mantenimiento.</p>



<p class="wp-block-paragraph">En este artículo, exploraremos una forma más limpia y eficiente de gestionar la renderización condicional en KumbiaPHP con return 1;. También profundizaremos en por qué este enfoque es preferible sobre el uso estándar de <em>return;</em> o estructuras <em>if-else</em> anidadas.</p>



<span id="more-2823"></span>



<h2 class="wp-block-heading">El Enfoque Tradicional: Uso de <em>if-else</em></h2>



<p class="wp-block-paragraph">Considera un escenario donde quieres mostrar un mensaje si no hay datos para mostrar y renderizar el resto de la vista solo cuando los datos están disponibles. Un enfoque típico podría verse así:</p>



<pre class="wp-block-code language-php"><code class="" data-line="">&lt;?php if (!$products): ?&gt;
    &lt;h2&gt;No hay productos disponibles&lt;/h2&gt;
&lt;?php else: ?&gt;
    &lt;h1&gt;Lista de Productos&lt;/h1&gt;
    &lt;ul&gt;
        &lt;?php foreach ($products as $product): ?&gt;
            &lt;li&gt;
                &lt;h3&gt;&lt;?= $product-&gt;nombre ?&gt;&lt;/h3&gt;
                &lt;img src=&quot;&lt;?= $product-&gt;imagen_url ?&gt;&quot; alt=&quot;&lt;?= $product-&gt;nombre ?&gt;&quot; /&gt;
                &lt;p&gt;&lt;strong&gt;Categoría:&lt;/strong&gt; &lt;?= $product-&gt;categoria ?&gt;&lt;/p&gt;
                &lt;p&gt;&lt;strong&gt;Descripción:&lt;/strong&gt; &lt;?= $product-&gt;descripcion ?&gt;&lt;/p&gt;
                &lt;p&gt;&lt;strong&gt;Precio:&lt;/strong&gt; $&lt;?= number_format($product-&gt;precio, 2) ?&gt;&lt;/p&gt;
                &lt;p&gt;&lt;strong&gt;Stock:&lt;/strong&gt; &lt;?= $product-&gt;stock ?&gt; unidades disponibles&lt;/p&gt;
                &lt;p&gt;&lt;strong&gt;SKU:&lt;/strong&gt; &lt;?= $product-&gt;sku ?&gt;&lt;/p&gt;
                &lt;a href=&quot;/productos/&lt;?= $product-&gt;id ?&gt;&quot; class=&quot;btn&quot;&gt;Ver Detalles&lt;/a&gt;
            &lt;/li&gt;
        &lt;?php endforeach ?&gt;
    &lt;/ul&gt;
&lt;?php endif; ?&gt;
</code></pre>



<p class="wp-block-paragraph">Aunque esto funciona, envolver todo el código de la vista dentro de un bloque <em>else</em> añade una indentación y complejidad innecesarias, especialmente en vistas más grandes.</p>



<h2 class="wp-block-heading">Renderización condicional en KumbiaPHP con return 1; Una Solución Más Limpia:</h2>



<p class="wp-block-paragraph">Para mejorar la legibilidad y mantener el código más limpio, podemos utilizar <em>return 1</em>; para salir de la vista de manera anticipada si no hay datos. Aquí está cómo se vería el código:</p>



<pre class="wp-block-code language-php"><code class="" data-line="">&lt;?php if (!$products) {
    echo &quot;&lt;h2&gt;No hay productos disponibles&lt;/h2&gt;&quot;;
    //View::partial(&#039;sin-datos&#039;); // o enviamos un partial
    return 1;
}?&gt;

&lt;h1&gt;Lista de Productos&lt;/h1&gt;
&lt;ul&gt;
    &lt;?php foreach ($products as $product): ?&gt;
        &lt;li&gt;
            &lt;h3&gt;&lt;?= $product-&gt;nombre ?&gt;&lt;/h3&gt;
            &lt;img src=&quot;&lt;?= $product-&gt;imagen_url ?&gt;&quot; alt=&quot;&lt;?= $product-&gt;nombre ?&gt;&quot; /&gt;
            &lt;p&gt;&lt;strong&gt;Categoría:&lt;/strong&gt; &lt;?= $product-&gt;categoria ?&gt;&lt;/p&gt;
            &lt;p&gt;&lt;strong&gt;Descripción:&lt;/strong&gt; &lt;?= $product-&gt;descripcion ?&gt;&lt;/p&gt;
            &lt;p&gt;&lt;strong&gt;Precio:&lt;/strong&gt; $&lt;?= number_format($product-&gt;precio, 2) ?&gt;&lt;/p&gt;
            &lt;p&gt;&lt;strong&gt;Stock:&lt;/strong&gt; &lt;?= $product-&gt;stock ?&gt; unidades disponibles&lt;/p&gt;
            &lt;p&gt;&lt;strong&gt;SKU:&lt;/strong&gt; &lt;?= $product-&gt;sku ?&gt;&lt;/p&gt;
            &lt;p&gt;&lt;strong&gt;Fecha de Lanzamiento:&lt;/strong&gt; &lt;?= date(&#039;d/m/Y&#039;, strtotime($product-&gt;fecha_lanzamiento)) ?&gt;&lt;/p&gt;
            &lt;p&gt;&lt;strong&gt;Calificación:&lt;/strong&gt; &lt;?= $product-&gt;calificacion ?&gt; estrellas&lt;/p&gt;
            &lt;a href=&quot;/productos/&lt;?= $product-&gt;id ?&gt;&quot; class=&quot;btn&quot;&gt;Ver Detalles&lt;/a&gt;
        &lt;/li&gt;
    &lt;?php endforeach ?&gt;
&lt;/ul&gt;
</code></pre>



<p>En este ejemplo:</p>
<ul>
<li>Si <em>$products</em> está vacío o es <em>false</em>, se muestra el mensaje «No hay productos disponibles» y la ejecución de la vista se detiene gracias a <em>return 1;</em>.</li>
<li>Si <em>$products</em> tiene datos, el código continúa ejecutándose y se muestra la lista detallada de productos sin necesidad de un bloque <em>else</em>.</li>
<li>El código es más limpio y fácil de leer al eliminar la indentación adicional.</li>
</ul>



<h2 class="wp-block-heading">Aplicación en Templates y Partials</h2>



<p class="wp-block-paragraph">La misma técnica puede aplicarse en <strong>templates</strong> y <strong>partials</strong>. Esto es útil cuando necesitas condicionar la inclusión de ciertas secciones o elementos de la interfaz de usuario.</p>



<h3 class="wp-block-heading">Ejemplo en un Partial</h3>



<p class="wp-block-paragraph">En un partial que muestra comentarios de un artículo:</p>



<pre class="wp-block-code language-php"><code class="" data-line="">&lt;?php
if (!$comments) {
    echo &quot;&lt;p&gt;No hay comentarios aún. ¡Sé el primero en comentar!&lt;/p&gt;&quot;;
    return 1;
}?&gt;

&lt;div class=&quot;comments&quot;&gt;
    &lt;h3&gt;&lt;?= count($comments) ?&gt; Comentarios&lt;/h3&gt;
    &lt;?php foreach ($comments as $comment): ?&gt;
        &lt;div class=&quot;comment&quot;&gt;
            &lt;p&gt;&lt;strong&gt;&lt;?= $comment-&gt;autor ?&gt;&lt;/strong&gt; dice:&lt;/p&gt;
            &lt;p&gt;&lt;?= $comment-&gt;contenido ?&gt;&lt;/p&gt;
            &lt;p&gt;&lt;em&gt;Publicado el &lt;?= date(&#039;d/m/Y H:i&#039;, strtotime($comment-&gt;fecha_publicacion)) ?&gt;&lt;/em&gt;&lt;/p&gt;
        &lt;/div&gt;
    &lt;?php endforeach ?&gt;
&lt;/div&gt;
</code></pre>



<h2 class="wp-block-heading">Entendiendo <em>View::render()</em> y <em>include</em></h2>



<p class="wp-block-paragraph">En KumbiaPHP, las vistas se renderizan usando el método <em>View::render()</em>, que internamente incluye el archivo de vista:</p>



<pre class="wp-block-code language-php"><code class="" data-line="">// Carga la vista
if (!include self::getView()) {
    throw new KumbiaException(&#039;Vista &quot;&#039; . self::getPath() . &#039;&quot; no encontrada&#039;, &#039;no_view&#039;);
}</code></pre>



<p class="wp-block-paragraph">La sentencia <em>include</em> en PHP devuelve <em>false</em> si falla al cargar el archivo (debido a que el archivo no existe, falta de permisos, etc.). Si el archivo incluido ejecuta un <em>return;</em> sin un valor, devuelve <em>null</em>, lo que la validación del  <em>include</em> se interpreta como <em>false</em>. Esto lleva a que <em>View::render()</em> crea que el archivo de vista no pudo ser incluido y lanza una excepción.</p>



<h3 class="wp-block-heading">La Importancia de <em>return 1;</em></h3>



<p class="wp-block-paragraph">Al usar <em>return 1;</em>, la vista devuelve <em>1</em>, lo que <em>include</em> interpreta como una inclusión exitosa. Esto permite que el proceso de renderización continúe sin problemas sin desencadenar una excepción.</p>



<h2 class="wp-block-heading">Beneficios de Usar <em>return 1;</em></h2>



<ul class="wp-block-list">
<li><strong>Código Más Limpio</strong>: Al eliminar bloques <em>else</em> innecesarios, el código es más sencillo y legible.</li>



<li><strong>Facilidad de Mantenimiento</strong>: Menos indentaciones y anidaciones facilitan la comprensión y modificación del código en el futuro.</li>



<li><strong>Consistencia</strong>: Puedes aplicar esta técnica en vistas, templates y partials de manera uniforme.</li>



<li><strong>Mayor Claridad</strong>: Separar la lógica de control del contenido principal mejora la claridad y organización del código.</li>
</ul>



<h2 class="wp-block-heading">Conclusión</h2>



<p class="wp-block-paragraph">Usar <em>return 1;</em> en las vistas de KumbiaPHP es una forma simple pero efectiva de gestionar la renderización condicional sin complicar tu código con estructuras <em>if-else</em> innecesarias. Asegura que tus vistas se ejecuten sin problemas y que el proceso de renderización continúe sin excepciones.</p>



<p class="wp-block-paragraph">Al adoptar este enfoque, puedes escribir vistas más limpias y mantenibles en tus aplicaciones KumbiaPHP. Pruébalo en tu próximo proyecto y experimenta la diferencia que hace en tu base de código.</p>



<p class="wp-block-paragraph"><em>¡Feliz codificación con KumbiaPHP!</em></p>
<p>La entrada <a href="https://kumbiaphp.com/blog/2024/10/14/optimizando-la-renderizacion-condicional-en-vistas-de-kumbiaphp-con-return-1/">Optimizando la Renderización Condicional en Vistas de KumbiaPHP con return 1;</a> se publicó primero en <a href="https://kumbiaphp.com/blog">KumbiaPHP Framework PHP en español</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://kumbiaphp.com/blog/2024/10/14/optimizando-la-renderizacion-condicional-en-vistas-de-kumbiaphp-con-return-1/feed/</wfw:commentRss>
			<slash:comments>3</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2823</post-id>	</item>
		<item>
		<title>Mejora en la configuración de errores en KumbiaPHP: Nueva funcionalidad Exception para entornos de producción</title>
		<link>https://kumbiaphp.com/blog/2024/09/30/mejora-en-la-configuracion-de-errores-en-kumbiaphp-nueva-funcionalidad-de-exception-para-entornos-de-produccion/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=mejora-en-la-configuracion-de-errores-en-kumbiaphp-nueva-funcionalidad-de-exception-para-entornos-de-produccion</link>
					<comments>https://kumbiaphp.com/blog/2024/09/30/mejora-en-la-configuracion-de-errores-en-kumbiaphp-nueva-funcionalidad-de-exception-para-entornos-de-produccion/#comments</comments>
		
		<dc:creator><![CDATA[Nelson Rojas]]></dc:creator>
		<pubDate>Mon, 30 Sep 2024 13:33:59 +0000</pubDate>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[buenas prácticas]]></category>
		<category><![CDATA[noticias]]></category>
		<guid isPermaLink="false">https://kumbiaphp.com/blog/?p=2851</guid>

					<description><![CDATA[<p>La entrada <a href="https://kumbiaphp.com/blog/2024/09/30/mejora-en-la-configuracion-de-errores-en-kumbiaphp-nueva-funcionalidad-de-exception-para-entornos-de-produccion/">Mejora en la configuración de errores en KumbiaPHP: Nueva funcionalidad Exception para entornos de producción</a> se publicó primero en <a href="https://kumbiaphp.com/blog">KumbiaPHP Framework PHP en español</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Es común que al desplegar aplicaciones, los desarrolladores olviden cambiar el flag PRODUCTION a <strong>true</strong>, lo que puede dejar expuesta información sensible a los usuarios finales. En este artículo, abordaremos la nueva funcionalidad implementada en KumbiaPHP para mitigar este riesgo, proporcionando una capa adicional de seguridad a través de la configuración <strong>Exception</strong>.</p>



<p><span id="more-2851"></span></p>



<h2>El problema de dejar PRODUCTION en false:</h2>



<p>De manera predeterminada, KumbiaPHP expone la información detallada de cualquier tipo de excepción, a modo de permitirle al desarrollador revisar y entender dónde debe realizar mejoras. El problema es que si se olvida de cambiar el flag de PRODUCCION y lo deja en su valor inicial (false) cuando los usuarios finales realicen alguna operación indebida, o exista algún fallo no previsto en el servidor, por ejemplo con el acceso a la base de datos o al sistema de archivo, Kumbia no tendrá contexto de que se trata de una aplicación en producción y expondrá todos los detalles.</p>



<h2>La nueva configuración Exception: </h2>



<p>La nueva funcionalidad, de forma definitiva, <strong>evita exponer</strong> información de excepciones, lo cual es un alivio tanto para los desarrolladores como para los clientes. Para permitir la visualización de excepciones se ha agregado un nuevo archivo llamado <strong>exception.php</strong>. En su contenido se pueden definir las direcciones IP que tendrán permiso para recibir los detalles entregados por KumbiaPHP tanto en desarrollo como en entorno productivo.</p>
<p><a href="https://kumbiaphp.com/blog/wp-content/uploads/2024/09/Screen-Shot-2024-09-26-at-10.14.54.png"><img loading="lazy" decoding="async" class="alignnone wp-image-2853 size-full" src="https://kumbiaphp.com/blog/wp-content/uploads/2024/09/Screen-Shot-2024-09-26-at-10.14.54.png" alt="" width="616" height="194" srcset="https://kumbiaphp.com/blog/wp-content/uploads/2024/09/Screen-Shot-2024-09-26-at-10.14.54.png 616w, https://kumbiaphp.com/blog/wp-content/uploads/2024/09/Screen-Shot-2024-09-26-at-10.14.54-300x94.png 300w" sizes="auto, (max-width: 616px) 100vw, 616px" /></a></p>



<h2>Ventajas de la nueva funcionalidad</h2>



<p>Dentro de las ventajas que se obtienen con esta nueva mejora podemos mencionar las siguientes:</p>
<ul>
<li>Seguridad: evita la exposición accidental de información sensible.</li>
<li><strong>Control</strong>: permite que sólo los desarrolladores o administradores puedan acceder a los detalles de los errores.</li>
<li>Fácil configuración: los usuarios solo necesitan añadir las IPs de confianza.</li>
</ul>
<h2>Cómo implementar la nueva funcionalidad:</h2>



<p>Para implementar la nueva funcionalida necesitamos seguir los siguientes pasos:</p>
<ol>
<li>Configurar las direcciones IP en el archivo <strong>exception.php</strong>.</li>
<li>Comprobar que los errores solo son visibles desde las IPs configuradas.</li>
</ol>
<h2>Caché:</h2>
<p>Desde esta nueva funcionalidad, el flag PRODUCTION asignado con el valor <strong>true</strong>, sólo será reponsable de habilitar el uso de la caché para el sitio web.</p>
<h2>Recordatorio:</h2>
<p>Nunca está demás dejar un recordatorio extra: aunque estés en modo desarrollo, si no se incluyen las direcciones IP dentro del archivo <strong>exception.php</strong> verán únicamente el error clásico, sin todos los detalles. Por lo tanto, <strong>no se olviden</strong> de agregar su propia dirección dentro de la nueva configuración.</p>
<h2>Conclusión:</h2>



<p>La nueva configuración de <strong>Exception</strong> en KumbiaPHP es un gran paso hacia la seguridad en entornos de producción, permitiendo que sólo quienes están autorizados puedan ver los detalles de los errores. Este tipo de mejoras no sólo protegen nuestras aplicaciones, sino que también promueven buenas prácticas en el desarrollo. De todos modos, el equipo está trabajando en <strong>agregar funcionalidades</strong> para esta nueva característica, así que no te pierdas las próximas mejoras que publicaremos también en nuestro blog.</p>
<p>Mucho ánimo a todos en nuestra comunidad, y como siempre les decimos&#8230; ¡larga vida a KumbiaPHP!</p>
<p>¡Un abrazo!</p>
<p>La entrada <a href="https://kumbiaphp.com/blog/2024/09/30/mejora-en-la-configuracion-de-errores-en-kumbiaphp-nueva-funcionalidad-de-exception-para-entornos-de-produccion/">Mejora en la configuración de errores en KumbiaPHP: Nueva funcionalidad Exception para entornos de producción</a> se publicó primero en <a href="https://kumbiaphp.com/blog">KumbiaPHP Framework PHP en español</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://kumbiaphp.com/blog/2024/09/30/mejora-en-la-configuracion-de-errores-en-kumbiaphp-nueva-funcionalidad-de-exception-para-entornos-de-produccion/feed/</wfw:commentRss>
			<slash:comments>1</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2851</post-id>	</item>
		<item>
		<title>KumbiaPHP 1.2 optimizado para PHP 8: código simplificado y mayor velocidad</title>
		<link>https://kumbiaphp.com/blog/2024/09/26/kumbiaphp-1-2-optimizado-para-php-8-codigo-simplificado-y-mayor-velocidad/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=kumbiaphp-1-2-optimizado-para-php-8-codigo-simplificado-y-mayor-velocidad</link>
					<comments>https://kumbiaphp.com/blog/2024/09/26/kumbiaphp-1-2-optimizado-para-php-8-codigo-simplificado-y-mayor-velocidad/#comments</comments>
		
		<dc:creator><![CDATA[HenryStivens]]></dc:creator>
		<pubDate>Thu, 26 Sep 2024 18:26:42 +0000</pubDate>
				<category><![CDATA[PHP]]></category>
		<category><![CDATA[noticias]]></category>
		<category><![CDATA[php8]]></category>
		<guid isPermaLink="false">https://kumbiaphp.com/blog/?p=2802</guid>

					<description><![CDATA[<p>La entrada <a href="https://kumbiaphp.com/blog/2024/09/26/kumbiaphp-1-2-optimizado-para-php-8-codigo-simplificado-y-mayor-velocidad/">KumbiaPHP 1.2 optimizado para PHP 8: código simplificado y mayor velocidad</a> se publicó primero en <a href="https://kumbiaphp.com/blog">KumbiaPHP Framework PHP en español</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Estamos emocionados de anunciar el lanzamiento de la <a href="https://github.com/KumbiaPHP/KumbiaPHP/releases/tag/v1.2.1" target="_blank" rel="noopener">versión 1.2 de KumbiaPHP</a> (Disponible desde el 11 de marzo del año en curso), una actualización que marca un hito significativo en la evolución de nuestro framework. <strong>KumbiaPHP 1.2 optimizado para </strong><a href="https://www.php.net/releases/8.0/es.php" target="_blank" rel="noopener">PHP 8</a> trae consigo mejoras en el rendimiento y la eficiencia, ya que aprovecha al máximo las capacidades de PHP 8, llevando tu desarrollo al siguiente nivel.</p>



<h2>KumbiaPHP 1.2 optimizado para PHP 8: Adopción total y ventajas</h2>
<p>Una de las principales novedades de <strong>KumbiaPHP 1.2</strong> es su completa compatibilidad con PHP 8. Si ya estás utilizando PHP 8 o tienes planes de actualizarte pronto, esta versión de KumbiaPHP es esencial para ti. PHP 8 introduce una serie de mejoras y nuevas características que permiten escribir código más limpio, eficiente y moderno. Al adoptar estas innovaciones, hemos optimizado el núcleo de KumbiaPHP, logrando una reducción significativa en las líneas de código.</p>



<span id="more-2802"></span>


<div class="wp-block-image">
<figure class="aligncenter size-full"><a href="https://kumbiaphp.com/blog/wp-content/uploads/2024/07/kumbia-php-8-1.jpg"><img loading="lazy" decoding="async" width="750" height="282" src="https://kumbiaphp.com/blog/wp-content/uploads/2024/07/kumbia-php-8-1.jpg" alt="" class="wp-image-2811" srcset="https://kumbiaphp.com/blog/wp-content/uploads/2024/07/kumbia-php-8-1.jpg 750w, https://kumbiaphp.com/blog/wp-content/uploads/2024/07/kumbia-php-8-1-300x113.jpg 300w" sizes="auto, (max-width: 750px) 100vw, 750px" /></a></figure>
</div>


<h2>Un núcleo más ligero y rápido</h2>
<p>Gracias a las nuevas características de PHP 8, hemos logrado simplificar y reducir el núcleo de KumbiaPHP. Esto se traduce en menos líneas de código, y lo convierte en un framework aún más rápido y eficiente. Menos código significa menos posibilidades de errores y un rendimiento mejorado, lo cual es crucial para el desarrollo de aplicaciones modernas y escalables.</p>
<h2>Todo funciona igual, pero de forma más eficiente</h2>
<p>Sabemos lo importante que es la estabilidad y la compatibilidad para nuestros usuarios. Por eso, aunque hemos realizado cambios significativos en el núcleo, el funcionamiento general de KumbiaPHP sigue siendo el mismo. Puedes actualizar a la versión 1.2 con la confianza de que tu aplicación continuará funcionando como antes, pero con las mejoras en rendimiento y eficiencia que PHP 8 ofrece.</p>
<h2>Futuras actualizaciones y nuevas librerías</h2>
<p>La versión 1.2 de KumbiaPHP es sólo el comienzo. En las próximas versiones menores, continuaremos aprovechando las ventajas de PHP 8, incorporando nuevas librerías y actualizaciones que enriquecerán nuestro framework. Estamos comprometidos en mantener a KumbiaPHP a la vanguardia de la tecnología, proporcionando a nuestros usuarios las herramientas necesarias para desarrollar aplicaciones robustas y eficientes.</p>
<h2>Recomendación adicional</h2>
<p>Dado que PHP 8.0 cumplió su ciclo de vida, sería recomendable ir adaptándose a las versiones más modernas que actualmente tienen soporte activo como la 8.2 y 8.3.</p>
<h2>¿Por qué actualizar a KumbiaPHP 1.2?</h2>
<ul>
<li><strong>Compatibilidad Total con PHP 8:</strong> Aprovecha todas las mejoras y nuevas características de PHP 8.</li>
<li><strong>Menos Código, Más Eficiencia:</strong> Un núcleo más ligero que mejora el rendimiento de tu aplicación.</li>
<li><strong>Estabilidad Garantizada:</strong> Continúa desarrollando con la tranquilidad de que todo funciona igual.</li>
<li><strong>Futuras Mejoras:</strong> Nuevas librerías y actualizaciones que seguirán optimizando tu experiencia de desarrollo.</li>
</ul>
<p>¡Actualiza hoy mismo a <strong>KumbiaPHP 1.2 optimizado para PHP 8</strong> y lleva tu desarrollo al siguiente nivel!</p>





<p> </p>
<p> </p>
<p>La entrada <a href="https://kumbiaphp.com/blog/2024/09/26/kumbiaphp-1-2-optimizado-para-php-8-codigo-simplificado-y-mayor-velocidad/">KumbiaPHP 1.2 optimizado para PHP 8: código simplificado y mayor velocidad</a> se publicó primero en <a href="https://kumbiaphp.com/blog">KumbiaPHP Framework PHP en español</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://kumbiaphp.com/blog/2024/09/26/kumbiaphp-1-2-optimizado-para-php-8-codigo-simplificado-y-mayor-velocidad/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2802</post-id>	</item>
		<item>
		<title>Cómo crear modelos de forma correcta</title>
		<link>https://kumbiaphp.com/blog/2022/09/10/crear-modelos-de-forma-correcta/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=crear-modelos-de-forma-correcta</link>
					<comments>https://kumbiaphp.com/blog/2022/09/10/crear-modelos-de-forma-correcta/#comments</comments>
		
		<dc:creator><![CDATA[Nelson Rojas]]></dc:creator>
		<pubDate>Sat, 10 Sep 2022 17:34:02 +0000</pubDate>
				<category><![CDATA[Tutoriales y screencast]]></category>
		<guid isPermaLink="false">https://kumbiaphp.com/blog/?p=2676</guid>

					<description><![CDATA[<p>La entrada <a href="https://kumbiaphp.com/blog/2022/09/10/crear-modelos-de-forma-correcta/">Cómo crear modelos de forma correcta</a> se publicó primero en <a href="https://kumbiaphp.com/blog">KumbiaPHP Framework PHP en español</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Bienvenidos a este post que trata sobre el cómo crear modelos de forma correcta para aplicaciones que utilizan el patrón de diseño MVC: Modelo, Vista, Controlador.</p>
<p>Una parte importante del trabajo dentro de un Framework MVC es el buen uso de los Modelos. </p>
<p>El modelo es <strong>responsable de mantener el estado de la aplicación</strong>. A veces este estado es transitorio, y dura sólo un par de interacciones con el usuario. Otras veces el estado es permanente y se almacena fuera de la aplicación, a menudo en una base de datos.</p>
<p>Un modelo es algo más que datos; impone todas las reglas de negocio que se aplican a esos datos. Por ejemplo, si un descuento no debe aplicarse a los pedidos de menos de de 20 euros, el modelo aplicará la restricción. Esto tiene sentido; al poner la implementación de estas reglas de negocio en el modelo, nos aseguramos de que nada más en la aplicación puede hacer que nuestros datos <strong>no sean válidos</strong>. El modelo actúa como tanto un <strong>guardián</strong> como un <strong>almacén de datos</strong>.</p>
<p><span id="more-2676"></span></p>
<p>Otra definición para el modelo es la <a href="https://en.wikipedia.org/wiki/Model%E2%80%93view%E2%80%93controller" target="_blank" rel="noopener">siguiente</a>: es el componente central del patrón (MVC). Es la estructura de datos dinámica de la aplicación, independiente de la interfaz de usuario. Gestiona directamente los datos, la lógica y las reglas de la aplicación.</p>
<p>En muchos casos, especialmente cuando uno comienza a trabajar en MVC, se cree que los modelos son <strong>únicamente</strong> para la gestión de la persistencia y la consulta de los datos de una base de datos (o de un repositorio)</p>
<h2>Fundamentos</h2>
<p>Antes de ahondar en los ejemplos y en los errores clásicos, nos gustaría mostrarte una imagen que puede ser de ayuda respecto de la forma en la que deberíamos construir nuestras aplicaciones usando el patrón descrito por <strong>Trygve Reenskaug</strong> (MVC)</p>
<p> </p>


<div class="wp-block-image">
<figure class="aligncenter size-full"><a href="https://kumbiaphp.com/blog/wp-content/uploads/2022/06/UrtaH.png"><img loading="lazy" decoding="async" width="596" height="232" src="https://kumbiaphp.com/blog/wp-content/uploads/2022/06/UrtaH.png" alt="comparación entre mala y buena implementación de modelos en mvc" class="wp-image-2678" srcset="https://kumbiaphp.com/blog/wp-content/uploads/2022/06/UrtaH.png 596w, https://kumbiaphp.com/blog/wp-content/uploads/2022/06/UrtaH-300x117.png 300w" sizes="auto, (max-width: 596px) 100vw, 596px" /></a></figure>
</div>


<p>La imagen, que es gentileza del Framework CakePHP, nos indica que una aplicación mal diseñada (Bad cake) tiene mucho código en los controladores y poco en las vistas y modelos. En la práctica, los controladores deberían servirnos principalmente para gestionar el Routing (las urls), interactuar con los modelos y despachar las vistas. En contraposición, una buena implementación (Good cake), debería contener más código en los modelos y menos en las vistas y controladores.</p>
<p>Volvamos un poco a lo que se mencionaba sobre el problema de los recién iniciados en MVC. Si bien es común que un modelo gestione datos de una base de datos, también sirve para gestionar «cosas» que no tienen relación con ello. Un ejemplo puede ser un modelo para un carro de compras. Es completamente factible llevar a cabo esta tarea sin persistencia en el DBMS (Database Management System). Bastaría con hacerlo con el objeto de sesión. Por otro lado, un modelo también podría encargarse de los pagos electrónicos, y luego apoyarse de otro que persista datos. Un modelo podría estar dedicado a la realización de cálculos específicos, otro del envío de notificaciones (SMS, Whatsapp, e-mail, etc), otro de la ejecución de tareas por shell dentro del servidor, y así sucesivamente.</p>
<p><strong>¿Qué es lo más común?</strong></p>
<p>Que las personas definan un modelo heredando de la clase del ORM (Object Relational Mapping) y, por ejemplo, en el caso de las notificaciones o el carro de compras, bastaría con que se utilizara una clase simple.</p>
<p>Vale, que aún no hay ejemplos porque nos quedan algunos <strong>fundamentos</strong> que debemos considerar.</p>
<h3>DRY</h3>
<p>Para muchos desconocido por sus siglas, pero viene del inglés <strong>Don&#8217;t Repeat Yourself</strong>. En buen castellano sería «No te repitas». ¿Qué significa esto? Significa que debemos gestionar cada «trozo de código» a su labor respectiva, en un único lugar. ¿Y qué tiene de malo copiar y pegar código? Cuando uno tiene mucho código repetido se rompe el principio DRY.</p>
<p>La repetición puede ser principalmente por desconocimiento de las herramientas que provee el Framework, o la clase de la que uno hereda. Por lo tanto, <strong>haz tu tarea de estudiante</strong>: <em>revisa los métodos, la documentación y luego ponte manos a la obra para que <strong>no repitas cosas</strong> que ya están implementadas</em> (lo que comúnmente llamamos reinventar la rueda)</p>
<p>Una vez que no tengas ruedas repetidas, verás que realizar <strong>modificaciones</strong> será una tarea sencilla, evitando así la <strong>fragilidad</strong> del código.</p>
<h3>OOP</h3>
<p>En términos de Orientación a Objetos, muchas veces no tenemos tan clara la diferencia entre el uso de la herencia, métodos estáticos y métodos dinámicos. Este tipo de temas los veremos en los ejemplos.</p>
<h3>El ORM</h3>
<p>Debemos familiarizarnos con la librería que gestiona la persistencia y las consultas al motor de bases de datos, en especial sus métodos, propiedades y los <strong>callbacks</strong>. En esto último quisiera detenerme un momento. Los callbacks son la analogía a lo que en un motor de base de datos se conoce como <strong>triggers</strong> (disparadores). Existen diferentes tipos de triggers, pero en generar se clasifican en los que se ejecutan <strong>antes</strong> de una acción y los que lo hacen <strong>después</strong> (before y after respectivamente)</p>
<p>El nuevo <a href="https://github.com/KumbiaPHP/ActiveRecord" target="_blank" rel="noopener"><strong>LiteRecord</strong></a> implementa callbacks para las acciones de creación (_beforeCreate, _afterCreate), para actualización (_beforeUpdate, _afterUpdate) y para guardar (_beforeSave, _afterSave)</p>
<p>En palabras simples, si el modelo encuentra un método _beforeAlgo, ejecutará dicha función antes de que se ejecute el método «Algo» (asumiendo que «Algo» puede ser Create, Save, Update). Por otro lado un _afterAlgo, se ejecutará luego que la función «Algo» haya finalizado.</p>
<p>Estos temas también los iremos tratando con casos cotidianos. Puedes checar su documentación en este <a href="https://github.com/KumbiaPHP/ActiveRecord/blob/master/LiteRecord.php" target="_blank" rel="noopener">enlace</a>.</p>
<h3>Traits </h3>
<p>Desde la versión de PHP 5.4 se implementan los <a href="https://www.php.net/manual/es/language.oop5.traits.php" target="_blank" rel="noopener">Traits</a> (rasgos, características) Es una buena estrategia para continuar con el principio DRY. De pronto tienes propiedades o métodos que son compartidos entre diferentes clases. Puedes extraer esos métodos en un trait y luego indicar que la clase implementa dichos «rasgos». Así tendrás un único lugar para ellos y finalmente, si hay menos código «innecesario o repetitivo», habrá menos errores y será más fácil de hacer mantención/corrección del mismo.</p>
<p> </p>
<p> </p>
<p>La entrada <a href="https://kumbiaphp.com/blog/2022/09/10/crear-modelos-de-forma-correcta/">Cómo crear modelos de forma correcta</a> se publicó primero en <a href="https://kumbiaphp.com/blog">KumbiaPHP Framework PHP en español</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://kumbiaphp.com/blog/2022/09/10/crear-modelos-de-forma-correcta/feed/</wfw:commentRss>
			<slash:comments>2</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2676</post-id>	</item>
		<item>
		<title>KumbiaPHP Live #10</title>
		<link>https://kumbiaphp.com/blog/2020/10/15/kumbiaphp-live-10/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=kumbiaphp-live-10</link>
					<comments>https://kumbiaphp.com/blog/2020/10/15/kumbiaphp-live-10/#respond</comments>
		
		<dc:creator><![CDATA[HenryStivens]]></dc:creator>
		<pubDate>Thu, 15 Oct 2020 04:00:58 +0000</pubDate>
				<category><![CDATA[Lives]]></category>
		<guid isPermaLink="false">https://kumbiaphp.com/blog/?p=2568</guid>

					<description><![CDATA[<p>La entrada <a href="https://kumbiaphp.com/blog/2020/10/15/kumbiaphp-live-10/">KumbiaPHP Live #10</a> se publicó primero en <a href="https://kumbiaphp.com/blog">KumbiaPHP Framework PHP en español</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Las últimas noticias del mes de septiembre sobre el framework.</p>
<figure style="text-align: center;"><iframe loading="lazy" src="https://www.youtube.com/embed/10vAUC_IWUg" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" width="560" height="315" frameborder="0"></iframe></figure>
<p>Aquí pueden ver las <a href="https://www.youtube.com/playlist?list=PLryxHhRnr3164wRTybubUXT6R-gXCrI9f">transmisiones anteriores</a>.</p>
<p>La entrada <a href="https://kumbiaphp.com/blog/2020/10/15/kumbiaphp-live-10/">KumbiaPHP Live #10</a> se publicó primero en <a href="https://kumbiaphp.com/blog">KumbiaPHP Framework PHP en español</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://kumbiaphp.com/blog/2020/10/15/kumbiaphp-live-10/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2568</post-id>	</item>
		<item>
		<title>KumbiaPHP Live #9</title>
		<link>https://kumbiaphp.com/blog/2020/09/16/kumbiaphp-live-9/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=kumbiaphp-live-9</link>
					<comments>https://kumbiaphp.com/blog/2020/09/16/kumbiaphp-live-9/#respond</comments>
		
		<dc:creator><![CDATA[HenryStivens]]></dc:creator>
		<pubDate>Wed, 16 Sep 2020 03:23:00 +0000</pubDate>
				<category><![CDATA[Lives]]></category>
		<guid isPermaLink="false">https://kumbiaphp.com/blog/?p=2558</guid>

					<description><![CDATA[<p>La entrada <a href="https://kumbiaphp.com/blog/2020/09/16/kumbiaphp-live-9/">KumbiaPHP Live #9</a> se publicó primero en <a href="https://kumbiaphp.com/blog">KumbiaPHP Framework PHP en español</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>Las últimas noticias del mes de agost sobre el framework.</p>
<figure style="text-align: center;"><iframe loading="lazy" src="https://www.youtube.com/embed/GNUugU2whv0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen="" width="560" height="315" frameborder="0"></iframe></figure>
<p>Aquí pueden ver las <a href="https://www.youtube.com/playlist?list=PLryxHhRnr3164wRTybubUXT6R-gXCrI9f">transmisiones anteriores</a>.</p>
<p>La entrada <a href="https://kumbiaphp.com/blog/2020/09/16/kumbiaphp-live-9/">KumbiaPHP Live #9</a> se publicó primero en <a href="https://kumbiaphp.com/blog">KumbiaPHP Framework PHP en español</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://kumbiaphp.com/blog/2020/09/16/kumbiaphp-live-9/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2558</post-id>	</item>
		<item>
		<title>Live Reload en PHP</title>
		<link>https://kumbiaphp.com/blog/2020/08/18/live-reload-php/?utm_source=rss&#038;utm_medium=rss&#038;utm_campaign=live-reload-php</link>
					<comments>https://kumbiaphp.com/blog/2020/08/18/live-reload-php/#respond</comments>
		
		<dc:creator><![CDATA[HenryStivens]]></dc:creator>
		<pubDate>Tue, 18 Aug 2020 05:00:00 +0000</pubDate>
				<category><![CDATA[IDE]]></category>
		<category><![CDATA[Tutoriales y screencast]]></category>
		<category><![CDATA[livereload]]></category>
		<category><![CDATA[vscode]]></category>
		<guid isPermaLink="false">https://kumbiaphp.com/blog/?p=2536</guid>

					<description><![CDATA[<p>La entrada <a href="https://kumbiaphp.com/blog/2020/08/18/live-reload-php/">Live Reload en PHP</a> se publicó primero en <a href="https://kumbiaphp.com/blog">KumbiaPHP Framework PHP en español</a>.</p>
]]></description>
										<content:encoded><![CDATA[
<p>En el siguiente video mostramos como configurar<a href="https://code.visualstudio.com/"> Visual Studio Code</a> y los navegadores más populares, Google Chrome y Firefox,&nbsp; para obtener live reload o recarga automática funcionando correctamente con KumbiaPHP.</p>
<h2>Vscode, Google Chrome y Firefox con livereload</h2>
<figure style="text-align: center;"><iframe src="https://www.youtube.com/embed/XXYpuMhkbHk" allowfullscreen="allowfullscreen" loading="lazy" width="560" height="315" frameborder="0"></iframe>
<figcaption>Live Reload en PHP</figcaption>
</figure>
<p>Extensión LiveReload para Visual Studio Code: <a href="https://marketplace.visualstudio.com/items?itemName=ziishaned.livereload">https://marketplace.visualstudio.com/items?itemName=ziishaned.livereload</a></p>
<p>Extensión LiveReload++ para Google Chrome: <a href="https://chrome.google.com/webstore/detail/livereload%20%20/ciehpookapcdlakedibajeccomagbfab">https://chrome.google.com/webstore/detail/livereload++/ciehpookapcdlakedibajeccomagbfab</a></p>
<p>Extensión LiveReload para Firefox: <a href="https://addons.mozilla.org/es/firefox/addon/livereload-web-extension/">https://addons.mozilla.org/es/firefox/addon/livereload-web-extension/</a></p>
<p>La entrada <a href="https://kumbiaphp.com/blog/2020/08/18/live-reload-php/">Live Reload en PHP</a> se publicó primero en <a href="https://kumbiaphp.com/blog">KumbiaPHP Framework PHP en español</a>.</p>
]]></content:encoded>
					
					<wfw:commentRss>https://kumbiaphp.com/blog/2020/08/18/live-reload-php/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
		<post-id xmlns="com-wordpress:feed-additions:1">2536</post-id>	</item>
	</channel>
</rss>
