Una pregunta que se hace mucha gente que está queriendo empezar con PHP es, habiendo tantos frameworks y habiendo escuchado cosas tan buenas de los frameworks, ¿vale la pena aprender PHP «a secas»?
Qué es un framework
Empecemos por la definición para entender de qué estamos hablando: un framework es, ante todo, un conjunto de código que ya está escrito y que resuelve una cantidad de problemas genéricos (problemas que muchas aplicaciones diferentes deben resolver).
En definitiva, un framework es un punto de partida muy bueno para una aplicación de cierta complejidad, podrías pensarlo como un atajo.
Cómo está hecho un framework
Salvo casos muy excepcionales (como Phalcon), los frameworks están escritos usando el mismo lenguaje que los programas «finales». En el caso de aplicaciones PHP, los frameworks son, técnicamente, código PHP.
De modo que, para comprender qué es lo que hace un framework necesitas conocer el lenguaje.
¿Es necesario conocer PHP para usar un framework PHP?
Pregunta difícil de responder :).
Yo diría que sí. Aunque sea muy por encima, se necesitan algunas nociones de Programación Orientada a Objetos (y específicamente de PHP para comprender la sintaxis).
Digamos que si entendés lo que significa esto:
<?php
use MiFramework\App;
$app = new App();
$app->run();
Sabés lo suficiente como para empezar a aprender a usar un framework.
¿Es conveniente conocer PHP para usar un framework PHP?
Siempre es bueno conocer las bases de las herramientas que uno usa.
Yo, por ejemplo, empecé estudiando C y C++ y, aunque ahora ya no los uso, conocer por dentro cómo funcionan lenguajes de más bajo nivel me permitió tener una comprensión mucho mayor de qué es lo que hago y, de esa forma, aprovechar mejor los recursos a mi alcance.
Particularmente, cuando se trata de PHP, saber hacer las cosas sin framework te permite:
Avanzar ahí donde el framework elegido puede no ser ideal (o tus conocimientos sobre él no son suficientes)
Meterte en el código del framework (no necesariamente para hacer mejoras, pero muchas veces identificar errores es más simple si podés hacer esto)
Conocer nuevos modos de resolver problemas (Mediante una herramienta como xdebug podés seguir el código mientras se ejecuta e ir analizándolo)
Conclusión
Según el nivel en que te encuentres actualmente te recomendaría:
Si conocés PHP pero no dominás por completo la Programación Orientada a Objetos te conviene adquirir esos conocimientos (Este libro puede ayudarte)
Si ya estás familiarizado con la Programación Orientada a Objetos en PHP tenés todo lo necesario para sumergirte en un framework (Este curso puede ayudarte)
Muchos clientes se acercan a cualquier desarrollador con la idea de agregar a su sitio un «carrito de compras» pero, cuando indagamos un poco más vemos que el tema no es tan simple.
Por ejemplo: ¿sirve de algo el carrito de compras sin la posisbilidad de realizar el pago al final?
Pero bueno, para no hacer un post enorme, comencemos por la parte del carrito propiamente dicho y dejemos el tema de los pagos para otro.
Qué puede hacerse con un carrito de compras
El carrito de compras es un espacio donde un visitante puede llevar registro de los productos que desea comprar.
Desde el punto de vista técnico/funcional, debe ser posible:
Ingresar productos
Quitar productos
Ver los productos existentes
Confirmar la compra
Para poder ingresar productos al carrito será necesario visualizar cuáles son los productos disponibles en la tienda.
Qué se necesita para armar un carrito de compras
La implementación de todo el mecanismo de administración del carrito requerirá de:
Algún tipo de base de datos que contenga el catálogo de productos
Una aplicación que permita al visitante:
Ver ese catálogo
Ver los detalles de cada producto
Agregar productos a su carrito
Ver los contenidos de su carrito
Eliminar productos del carrito
Confirmar su compra
Una pasarela de pagos para completar la transacción
Por simplicidad imaginemos que tenemos una primera página tipo catalog.php:
Estoy dejando de lado unos cuantos detalles para no complicar el ejemplo: como ser categorías de productos, cantidad a agregar en cada interacción, etc…
Continuemos por el archivo add_to_cart.php.
Aquí es donde reside la clave de la cuestión: el carrito debe acompañar al visitante durante toda su estadía en el sitio.
Precisamente, la idea del carrito es permitir que la compra se vaya armando conforme el usuario va descubriendo los productos.
De modo que necesitaremos un medio de almacenamiento que persista durante la navegación.
A estos efectos php pone a nuestra disposición el arreglo $_SESSION.
Es ahí donde vamos a almacenar los productos seleccionados por el visitante:
De este modo guardamos los ids de los productos seleccionados y su cantidad.
No es necesario guardar más que los ids de producto ya que con eso será suficiente para recuperar toda la información a la hora de mostrar el carrito o confirmar la compra.
Queda por completar los archivos de ver el detalle del producto y remover del carrito pero creo que con lo que viste hasta aquí no deberías tener problemas para armarlos.
Un detalle que haría más amena la experiencia para el usuario sería utilizar AJAX para meter y sacar productos del carrito.
Y, por supuesto, deberás tener un enlace para realizar el pago.
Es una necesidad bastante usual la de recoger información disponible en Internet.
Algunos sitios permiten hacerlo en forma amigable exponiendo algún tipo de API, que puede ser consumida conectándose a un webservice.
En otros casos, lo mejor que puede hacerse es algo de WebScrapping.
Claro que es una técnica muy poco fiable y bastante costosa en términos computacionales, pero… si no queda otra…
En este caso, de lo que se trata es de extraer las direcciones de correo electrónico presentes en una página cualquiera, por ejemplo:
Se trata de un proceso de dos pasos
Cómo obtener los contenidos de una página usando PHP
El primer paso es obtener el contenido de la página. En realidad, lo que nos interesa es el HTML de la página, las imágenes, hojas de estilo y demás no es necesario en este momento.
Una forma muy sencilla de conseguirlo es usar la función file_get_contents:
Cómo identificar correos electrónicos dentro de un texto
El segundo problema a resolver es, una vez que obtuvimos todo ese texto HTML… ¿cómo podemos determinar qué direcciones de correo electrónico hay dentro?
Afortunadamente, las direcciones de correo electrónico siguen un patrón bastante estructurado: todas tienen una @ en el medio y, al menos, un . a la derecha.
Podríamos usar una expresión mucho más compleja, pero comencemos por esta.
Nuestro aliado en esta ocasión será la función preg_match_all:
Un cliente con el que trabajé estaba buscando aumentar el tamaño de su base de datos para realizar mailings y me pidió que le diseñe un robotito para extraer las direcciones de correo que estén presentes en las páginas resultantes de ciertas búsquedas de Google.
Si bien personalmente no lo considero algo muy productivo (Discusión aparte sobre la efectividad/ética de enviar correo no deseado o si realmente se trata de correo no deseado cuando se ofrece una solución que realmente va a ayudar a quien lo reciba), me pareció interesante el desafío técnico (y también, hay que reconocerlo, a veces simplemente hay que darle al cliente lo que quiere :)).
Lo primero que se me ocurrió fue que, así como hay APIs para entrar a Gmail, a GoogleDocs y demás, debía haber alguna para usar el motor de búsqueda y obtener los datos en formato JSON, XML o algún otro formato digno de un webservice.
Y ahí vino mi primera sorpresa (Eso es lo que me fascina de la programación: siempre hay cosas nuevas para aprender :)): a Google no le gusta que los robots le usen su motor (Irónico, ¿no? ellos viven de scrappear toda la web, pero…).
De modo que, para lograr esta hazaña había que arremangarse y parsear HTML (Algo como lo que te comenté sobre cómo acceder a sitios que no te dan API) o bien, siendo que se trata de un sitio archi-conocido, buscar en Packagist.org que seguro iba a tener algo piola para arrancar al menos.
Como de costumbre, Packagist no me defraudó y conocí el proyecto SERPS.
Qué es el proyecto SERPS
El proyecto SERPS es un esfuerzo por crear un conjunto de herramientas que permitan suplir esta falta, es decir, es un set de bibliotecas que permite (o, mejor dicho, permitirá) automatizar las búsquedas en diferentes motores (Actualmente sólo Google está implementado).
Es bastante interesante desde su arquitectura, bien modular y de bajo acoplamiento (Se nota la aplicación del patrón strategy).
A nivel práctico, se trata de una capa de abstracción muy útil para «olvidarnos» de la complejidad de interpretar los resultados de una búsqueda (¡y los caprichos de los pedidos!).
Preparando el proyecto para usar SERPS
SERP está diseñado para ser usado con composer. Al principio de su documentación hay un ejemplo de archivo composer.json que te recomiendo copiar y pegar (Yo intenté incluir las dependencias que iba necesitando y no funcionó nada :p):
Con esta configuración (y, obviamente, un composer install) tenés todo lo necesario para hacer queries a Google usando PHP.
Cómo hacer una búsqueda en Google usando SERPS
Como decía al comienzo, a Google no le gustan los robots, así que… hay que hacer de cuenta que la búsqueda la hace una persona. Obviamente, una persona que está usando algún navegador. Todo esto se traduce en usar un User-Agent adecuado.
Te muestro un ejemplo de lo que yo hice:
#!/usr/bin/php
<?php
use Serps\HttpClient\CurlClient;
use Serps\Core\Browser\Browser;
use Serps\SearchEngine\Google\GoogleClient;
use Serps\SearchEngine\Google\GoogleUrl;
require_once 'vendor/autoload.php';
$userAgent = "Mozilla/5.0 (Windows NT 10.0) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/40.0.2214.93 Safari/537.36";
$browserLanguage = "es-AR";
$browser = new Browser(new CurlClient(), $userAgent, $browserLanguage);
$googleClient = new GoogleClient($browser);
$googleUrl = new GoogleUrl();
foreach ( file($argv[1]) as $searchTerms ) {
$googleUrl->setSearchTerm($searchTerms);
$response = $googleClient->query($googleUrl);
$results = $response->getNaturalResults();
foreach ($results as $result) {
if ( $result->url ) {
echo $result->url . PHP_EOL;
}
}
}
En mi caso, el script toma como parámetro un archivo (que asumo tiene una línea por búsqueda que se quiere hacer) y emite los links encontrados.
Fijate que sencillo:
Se crea un objeto Serps\SearchEngine\Google\GoogleClient usando un objeto Serps\Core\Browser\Browsercomo interface para realizar la comunicación HTTP y otro objeto Serps\SearchEngine\Google\GoogleUrlpara armar la consulta como es debido.
Luego de consultar se obtienen los resultados naturales (Es decir, aquellos resultados no pagos) y, por cada uno se emite el link. En mi caso todo esto va acompañado de otro script que busca direcciones de correo electrónico dentro de una página web y emite los resultados como para ser incorporados a un archivo .csv.
Ejemplo de uso del script
Ya teniendo las dos herramientas (la que busca links en Google y la que busca direcciones de mail dentro de una página), es muy fácil componerlas (Si usás algún sistema operativo POSIX como Linux al menos :p):
./get_links.php terms.csv | ./get_emails.php
En el archivo terms.csv se escribe, línea por línea, las búsquedas que quiero realizar, el script get_links.php emite cada resultado que obtiene y get_emails.php toma sus datos de la entrada estándar… justo lo que se necesita para usar pipes :).
Y claro, la frutilla del postre es guardar la salida de get_emails.php en un nuevo archivo .csv:
La tarea de hacer webscrapping no es muy grata que digamos (Especialmente porque los grandes esfuerzos que se hacen pueden resultar en vano si el sitio a ser scrappeado cambia su layout…), pero… a veces resulta útil.
Y, si bien algunos sitios hacen lo posible para «protegerse» de este tipo de prácticas… es poco lo que pueden hacer para evitarlas al 100%…
La pregunta que dió origen a este post era un poco más amplia:
Pero como ya hablé de cómo consumir webservices (Sean REST o SOAP) me voy a concentrar en la parte que me llamó la atención: cómo pasar de JSON a CSV.
Aclaremos los tantos antes de ir a los detalles:
Qué es JSON
JSON significa JavaScript Object Notation, es decir: notación de objetos de JavaScript. Está más allá del alcance de este artículo (y de este blog en general) hablar de las bondades (o falta de ellas) de JavaScript… hay mucho material muy bueno al respecto.
El punto es que, más allá de lo que a vos te guste o no, JavaScript tiene una sintaxis muy práctica para describir los objetos: todo lo que esté encerrado entre {} es un objeto (Con la excepción tal vez del cuerpo de las funciones…).
Esto lo hace un formato sumamente conveniente para el intercambio de información de estructuras complejas, ya que constituye un modo muy simple de pasar de un objeto en memoria a una representación textual (que puede ser enviada a través de un protocolo de intercambio de textos… por ejemplo HTTP :)).
Se ve muy simple (¡y lo es!) pero tiene un pequeño inconveniente: su sintaxis es muy poco permisiva (Dejá una , suelta y agarrate :p), por lo tanto, es muy conveniente usar las funciones propias de PHP para manipularlo (json_encode y json_decode).
Y acá me da un poco de nostalgia hablar del primer post que escribí para este blog, pero pienso que puede aportar a la respuesta saber cómo iterar sobre un JSON usando PHP.
Qué es CSV
CSV significa Comma Separated Values (Valores separados por comas). Se trata de un formato de texto que también es utilizado para el intercambio de información entre sistemas.
Usualmente el contenido de este tipo de archivos es una sucesión de filas que corresponden con registros cuya cantidad de campos puede variar de uno a otro y la longitud de cada campo también varía.
Una primera salvedad que hay que hacer es que JSON es un formato que permite estructuras complejas (de múltiples niveles por ejemplo), mientras que CSV es un formato mucho más simple (Se basa en estructuras «planas»), con lo cual, algo se perderá en el camino (o habrá que hacer alguna suposición o transformación de la información).
A efectos prácticos, asumamos que el JSON de partida es de un único nivel, algo como:
Ahora, si la necesidad es más compleja… nada mejor que buscar un poco :).
Buscando buscando encontré esta herramienta: https://github.com/danmandle/JSON2CSV (No la probé pero parece interesante… ¿te animás a probarla y comentar?)
Mucho se habla de SEO (Search Engine Optimization) y muy poco es lo que realmente se sabe. Sin ser un experto en la materia (de hecho, como buen desarrollador, muy lejos estoy de serlo :p), tengo mis opiniones al respecto.
Más allá de qué es el SEO o mejor dicho, cómo operar en favor del SEO de un sitio, todo el mundo sabe que el SEO es algo bueno y, por lo tanto, cualquier cosa que lo perjudique es algo malo, ¿cierto?… No tan rápido :).
El SEO forma parte de una estrategia de adquisición de tráfico, un tema de Marketing Online que, dado que este no es un espacio para discutir sobre Marketing Online, está fuera de alcance.
A lo que sí quiero hacer referencia es a esta pregunta que vengo leyendo en varios lugares (Dicha con más o menos palabras):
¿Es mejor para el SEO de un sitio desarrollarlo usando php puro en lugar de algún framework standard?
La verdad… no entiendo bien cómo se llega a esa conclusión, pero bueno… intentaré dar una respuesta.
De qué se trata SEO
Sin entrar en muchos detalles, SEO se trata de disponer los contenidos y la estructura de un sitio de modo de facilitar a los motores de búsqueda (Google, Bing, etc…) la incorporación de un sitio a sus índices (Y de ese modo lograr que aparezca dentro de los resultados de búsqueda de los usuarios que queremos atraer… esperablemente en las primeras páginas).
Los factores que toman en cuenta los motores de búsqueda para decidir en qué posición colocan a cada sitio son muy variados y cambiantes constantemente (De eso viven los consultores SEO). Sin embargo, hay algunos que tienen especial relevancia, entre ellos, la velocidad de carga del sitio (y supongo que por este lado viene la pregunta).
Cómo afecta un framework a la velocidad de carga de un sitio
Es muy difícil hablar de frameworks como un genérico. Existen algunos que están especialmente orientados a manejar sitios de alto tráfico (y, por ende, a hacer un uso muy eficiente de los recursos), otros a generar código más sencillo de mantener (aún a costa de algo de performance).
Personalmente, desconfío de las ventajas de no usar un framework. En mi experiencia, siempre es más fácil optimizar algo que está bien estructurado que lo contrario.
De hecho, las mayores optimizaciones en lo que a performance se refieren vienen por el lado de la infraestructura más que del código (Por ejemplo, implementando un web server potente como NginX, poniendo más servidores, usando balanceadores de carga, cachés como Varnish y otra cantidad de truquitos por el estilo).
Existe una visión bastante arraigada (especialmente entre los programadores de nivel intermedio) de que los frameworks son mastodontes pesados que agregan una capa de complejidad y features muy probablemente innecesarios.
Es posible que así haya sido anteriormente (aunque lo dudo), pero la realidad de hoy es muy diferente. Los frameworks de PHP están sumamente atomizados (Es decir, al crear una aplicación podés combinar las partes que te resulten útiles sin sobrecargar tu aplicación).
Por otro lado, ¡generar código optimizado no es una tarea sencilla!
Programando para la web estamos lejos de los sistemas hechos en Assembler donde cada ciclo de reloj cuenta y nada garantiza que no usar un framework estándar genere mejor código que sí hacerlo.
Lo que sí garantiza no usar un framework estándar es tener que trabajar en resolver problemas que ya están resueltos (Lo que se dice reinvetar la rueda).
¿Puede un framework estándar ayudar al SEO?
De hecho sí, puede y bastante. Una muestra muy simple es el tema de las URLs amigables (Otro de los pocos «trucos» de SEO que conozco).
Hace un tiempo que a los motores de búsqueda les parece mejor una URL del tipo http://misito.com/un-tema-muy-popular que una del tipo http://misito.com/index.php?post_id=1271.
Generar este tipo de URLs a partir del contenido de una página no es una tarea trivial (Puede ser simple, pero mejor si alguien ya lo hizo, ¿no?) y después está el tema complementario… cómo llegar desde la URL http://misito.com/un-tema-muy-popular al post con id 1271.
De nuevo, no es la muerte de nadie armar este mecanismo, pero si un framework ya lo tiene hecho… ¿quién paga esas horas?
Conclusión
En última instancia, siempre se trata de una cuestión de comodidad personal, pero, aún cuando decidas no usar un framework, es importante poder tomar esa decisión con fundamentos y la preocupación por el SEO no es uno bueno.
Estás montando tu entorno de trabajo local para trabajar en un proyecto PHP.
Hay muchas cosas por definir pero una es segura: no vas a usar XAMPP ni nada parecido… después del último fiasco fue suficiente, hay que virtualizar sí o sí.
Y la pregunta es: ¿voy con Docker o con una VM?
Creeme que te entiendo, estuve mucho tiempo en tus zapatos.
Hoy por hoy mi elección es clara: Docker. Pero no te pido que me creas así sin más, dejame darte una breve explicación para que saques tu conclusión.
En qué se parecen y en qué se diferencian Docker y las Máquinas Virtuales
Docker es un sistema de administración de contenedores. Sin entrar en mucho detalle, diré que es un método para crear y administrar entornos de ejecución aislados del resto.
Las máquinas virtuales son sistemas de simulación de hardware.
¿Entonces…?
Las máquinas virtuales son, en cierta medida, más poderosas ya que permiten crear un entorno de computación «completamente» separado del host, donde puede instalarse, por ejemplo, un sistema operativo diferente de aquel del host.
Docker (o algún otro sistema de contenedores) en cambio no virtualiza hardware, si no software. Esto significa que sus posibilidades son algo más limitadas (Por ejemplo, montar un contenedor Linux en un host Windows es algo que, en principio no es posible).
Hasta aquí la balanza parece inclinarse hacia las VMs, ¿no? Entonces… ¿por qué deberías preferir Docker?
Los contenedores Docker son mucho más livianos que las VMs. Esto implica que:
Se inician/frenan mucho más rápido
Ocupan mucho menos espacio en el disco
Consumen muchos menos recursos del host
Todo esto hace que sea mucho más viable tener un gran número de contenedores Docker ejecutando en un mismo host, a diferencia de lo que ocurre con las máquinas virtuales.
Dejando estos detalles de implementación de lado, en la práctica las diferencias son mínimas. Cambia un poco la forma de configurar el entorno pero ambos se prestan muy bien para la automatización.
Tanto Docker como los sistemas de virtualización cuentan con interfaces de línea de comandos muy potentes y, sobre esas herramientas básicas se montan algunas más avanzadas (Vagrant para el caso de VMs y docker-compose para Docker) o incluso algunas con interface gráfica, lo cual facilita mucho su uso.
De modo que, siendo que el costo de implementar una o la otra es prácticamente igual, ¿por qué ir con la que más recursos consume?
Por supuesto que la realidad es más compleja, hay que analizar el caso por caso pero, en líneas generales, mi recomendación es ir con Docker.
Cómo arrancar con Docker
Bueno, este tema excede un poco el objetivo de este post, pero voy a intentar hacer un breve resúmen y dejarte algunas referencias que puedan ayudarte:
Este post está inspirado en un caso muy interesante que me tocó resolver para un cliente.
Un poco de contexto para que se entienda de dónde viene el tema:
Una buena parte de los clientes de mi cliente llegan a través de correos que se reciben en info@...., claramente, te imaginarás que, dentro de los muchos que llegan, una parte es SPAM y la otra son contactos genuinos.
Separar la paja del trigo sería un desafío realmente interesante (Que probablemente involucraría algo de procesamiento del lenguaje natural, IA y esas cosas tan divertidas), pero… por el momento el presupuesto dio sólo para mejorar un poco el proceso de tratamiento del trigo una vez haya sido debidamente identificado.
Muy bien, entonces, el punto era que se estaba queriendo, además de re-enviar los correos útiles al equipo de ventas, subirlos de inmediato al sistema de newsletters de la empresa (Obviamente, se trataba de MailChimp).
Decidimos entonces crear una cuenta de GMail a la cual la persona encargada de identificar los correos de potenciales clientes pudiera re-enviarlos (además de al equipo de ventas) y, a partir de ahí, tener un robot que los procesara e incorporara la lista de mailing.
Técnicamente se trata de cuatro problemas:
Cómo autorizar el acceso a GMail vía API
Cómo ingresar a GMail y descargar los correos
Cómo procesar los datos descargados para extraer las direcciones de correo
Cómo incorporar esos datos a MailChimp
Sobre el último de los problemas escribí acá, así que concentrémonos en los tres primeros:null
Cómo configurar el acceso a GMail vía API
Hay una primera parte que hace a la autorización de la aplicación (Muy parecido a lo que hicimos para entrar al Google Drive):
Logeate a la cuenta a la que vayas a querer acceder en forma programática
Y cuando llegue la pregunta, incorporá como dependencia google/apiclient.
En nuestro caso, nos interesan las clases Google_Client (Necesaria para acceder a cualquier servicio de Google) y Google_Service_Gmail (Específica para el procesamiento de peticiones a Gmail).
La creación de la instancia de Google_Client requiere de la existencia de un set de credenciales válidas (que se obtienen simplemente siguiendo un enlace que generará la propia aplicación).
Una vez obtenido este objeto lo usaremos para crear nuestra instancia de la segunda clase:
$service = new Google_Service_Gmail($client);
Y a partir de ahí usaremos la propiedad users_messages para traer los correos.
Cómo procesar correos descargados de GMail usando PHP
Una vez obtenido cada uno de los correos necesitaremos procesarlos.
Lo que sabemos es que los correos vienen codificados como texto MIME, con lo cual, necesitaremos algo de ayuda para procesarlos sin volvernos locos… por ejemplo, la ayuda de PHPMimeMailParser.
Claro que no todo es tan fácil… en particular, los mails en Gmail vienen además codificados usando base64 (Pero no el base64 que viene con PHP… es un base64 codificado para URLs… Nada muy terrible, sólo hay que saberlo para actuar en consecuencia: se necesita cambiar los caracteres - y _ por + y /respectivamente. Más detalles en https://medium.com/@jrdnrc/decoding-gmail-messages-in-php-408194aeb767).
Una vez hecho esto podremos extraer alegremente las diferentes partes del correo, por ejemplo:
$from = $parser->getHeader('from');
Para conocer el remitente. O:
$subject = $parser->getHeader('Subject')
Para el asunto.
Resultado final
Ahora sí, veamos el ejemplo completo.
Como usé Composer para instalar las librerías, lo primero que voy a mostrarte es el archivo composer.json:
Si aún estás en dudas, no dudes más: usa la clase, te ahorrará una gran cantidad de dolores de cabeza.
Con lo que la llamada se vería algo así como:
<?php
$url = 'https://secure.softwarekey.com/solo/webservices/XmlCustomerService.asmx?WSDL';
$client = new SoapClient($url);
$xmlr = new SimpleXMLElement("<CustomerSearch></CustomerSearch>");
$xmlr->addChild('AuthorID', 1);
$xmlr->addChild('UserID', 'mchojrin');
$xmlr->addChild('UserPassword', '1234');
$xmlr->addChild('Email', 'mauro.chojrin@leewayweb.com');
$params = new stdClass();
$params->xml = $xmlr->asXML(); // OJO: La propiedad xml es particular de este WebService, debes reemplazarla por el nombre del parámetro que espera recibir el servicio al que buscas conectarte
$result = $client->CustomerSearchS($params);
print_r($result);
echo PHP_EOL;
Si ejecutas este código te encontrarás con algo como:
Lo que seguramente te interese es lo que está dentro de la clave any, con lo cual, para obtenerlo podrías usar echo $result->CustomerSearchSResult->any; en lugar de print_r($result);. Aunque probablemente lo que quieras no sea mostrar el resultado explícitamente, si no procesarlo de alguna manera… ¿qué mejor que recurrir nuevamente a SimpleXMLElement?
Ya en el artículo sobre cliente REST di una pequeña definición de un WebService, por si no lo leíste te lo cuento:
Un WebService es una pequeña aplicación web diseñada para interactuar con otras aplicaciones (en lugar de hacerlo con personas).
Las dos aplicaciones que se comunican toman el rol de:
Servidor: quien expone el servicio
Cliente: quien lo consume
¿Qué es REST?
REST es un protocolo de intercambio de información basado en HTTP.
¿Cómo se implementa en PHP?
Los servicios web basados en REST suelen ser mucho más fáciles de crear (y consumir) que los basados en SOAP.
De hecho, cualquier aplicación PHP que hayas hecho podría ser un WebService REST! (Bueno… tal vez no uno muy útil, pero eso es otro tema :)).
Te muestro un ejemplo super simple:
<?php
echo json_encode( [ 'Hola' ] );
No está mal, ¿cierto?
En este caso lo que vemos es una aplicación que, al ser invocada usando curl http://localhost:8080/rest_server.php(Asumiendo que está montada sobre el servidor local) nos dará esta salida:
["Hola"]
El cliente que haya realizado dicha invocación deberá saber qué tipo de contenido le estamos enviando (¡y actuar en consecuencia!).
Podés probarlo iniciando el servidor de esta forma:
php -S localhost:8080 &
(El & para que el proceso se ejecute en background y puedas seguir).
En caso de que se hubiese producido un error (Por ejemplo, que el recurso buscado no se encontrara disponible), deberíamos usar la función http_response_code para enviar un aviso al cliente:
http_response_code( 404 );
Por último, una buena práctica es también hacer explícito el tipo de contenido que vamos a enviar al cliente:
header('Content-type: application/json');
De esta forma el cliente tiene algo más de información y puede tomar mejores decisiones.
En definitiva, si podés elegir, te recomiendo usar siempre servicios web basados en REST. Otro consejo es que tengas a mano los códigos de error HTTP (No es necesario saberlos todos de memoria, pero ayuda :)).
¿Qué ejemplos se te ocurren ahora que sabés armar servicios REST?