oriolrius.cat

Des del 2000 compartiendo sobre…

Tag: php

PHP5: passant objectes com a paràmetre en una crida SOAP

Reading time: 2 – 3 minutes

Update: LES CONCLUSIONS D’AQUEST ARTICLE SÓN ERRONEES MIREU: PHP5: passant i tornant objectes com a paràmetre en una crida SOAP (Part II)

Treballant en un projecte que estem programant en PHP5 em va sortir aquest dubte, sobretot després de llegir les limitacions dels servidors SOAP que implementa PHP5. El tema finalment té una resposta positiva: SI, PERO…. A continuació us poso un exemple de com funciona aquest tema amb el PHP5 i quines limitacions té.

Definim el servidor SOAP que com podeu veure és senzillissim, l’únic que fa el servidor és re-enviar el mateix objecte que ha rebut.

<php
class SOAPservice {
        function peticion($per) {
                return $per;
  }
}
$server = new SoapServer("server.wsdl");
$server->setClass("SOAPservice");
$server->handle();
?>

A continuació podeu veure el codi del client, és un codi molt senzill de només dues línies. Com podem veure primer definim la classe persona i abans de cridar el client SOAP instanciem la classe, després usem aquest objecte com a paràmetre a la crida SOAP. Capturem l’objecte que ens retorna el servidor SOAP i a continuació mostrem el seu contingut amb l’ordre print_r.

<?php
/*
 definim classe persona
*/
class persona {
        public $nom;
        function setNom($nom) {
                $this->nom=$nom;
        }
        function setCognom($cognom) {
                $this->cognom=$cognom;
        }
        function getNom() {
                return $this->nom;
        }
        function getCognom() {
                return $this->cognom;
        }
}
/*
 creem objecte tipus persona
*/
$myPersona=new persona;
$myPersona->setNom("el_nom");
$myPersona->setCognom("el_cognom");
/*
 fem una crida SOAP amb un objecte com a parametre
*/
$client = new SoapClient("server.wsdl");
$myObj=$client->peticion($myPersona);
/*
 mostrem objecte generic que retorna la crida SOAP
*/
print_r($myObj);
?>

Si mirem la sortida que ens dona quan cridem el client podem veure que l’objecte que torna no és del tipus persona sinó d’un tipus intern del PHP5 anomenat stdClass. Aquest objecte només disposa dels atributs públics. No podem accedir als atributs privats o protegits i hem perdut tots els mètodes siguin del tipus que siguin.

stdClass Object
(
    [nom] => el_nom
    [cognom] => el_cognom
)

Això és tot el que he pogut aconseguir, no és gaire però com a mínim a mi m’ha estat suficient.

Aprenent PROPEL amb 30min

Reading time: 2 – 4 minutes

Propel és un framework de PHP que permet accedir a les bases de dades usant objectes, ens ofereix una API molt senzilla que és capaç de filtrar les queries contra la base de dades perquè sigui completament transparents a la nostre aplicació. Perquè ens entenguem estem parlant de coses que de ben segur coneixeu com ara el DAO o el ORM.

grafic-propel.gif

Per fer-nos una idea per definir l’estructura d’una base de dades només cal que escribim un fitxer XML amb els camps de les taules, tipus, relacions, etc i el Propel farà la resta. Llavors el Propel es posa a generar totes les classes automàticament, i els fitxers .sql amb els esquemes de definició de les bases de dades. Amb les classes que ens ha generat el Propel podem accedir a totes les funcions bàsiques d’accés a la base de dades és el que se’n diu CRUD (def.wikipedia).

Si voleu aprofundir en tema us recomano que seguiu els passos que vaig seguir jo i amb 30min us sentireu com de la família:

  • QuickStart – Com crear les BBDD, taules i altre elements al voltant de les dades per tal de poder treballar de forma trivial amb elles
  • CRUD explica com usar les funcions bàsiques de CRUD amb Propel.
  • Esquemes dels fitxers XML. Quan definim l’esquema de la BBDD ens interessa coneixer a fons la sintaxis suportada per tal d’aprofitar al màxim les funcions del propel
  • Relacions entre taules. Donant una mica d’emoció a les dades, usant relacions entre taules senzilles.
  • Captura d’errors. Si ens interessa unificar les sortides d’error de Propel és molt senzill fer-ho.
  • Les relacions many-to-many (molts-a-molts) no estan suportades directament pel propel i s’han de fer a través d’una taula intermitja. Malgrat ens permet sortir del pas és un dels punts a evolucionar dins de propel. Si ens interessa millorar aquesta part podem incloure les nostres classes que implementin això pel nostre codi sense problemes dins de l’estructura estàndard del propel. De moment, si ho volem fer tal i com ens proposa el manual.

PHP4 vs PHP5

Reading time: 2 – 3 minutes

Tot llegint el PHP|Architect’s Guide to PHP Design Patterns (isbn: 0973589825) vaig trobar fa un parell de dies un petit llistat de quines eres les diferencies fonamentals entre PHP4 i PHP5, a part del tòpic que amb el motor de Zend 2.1 ara tenim suport de OOP i de que tothom em digui que el model d’objectes que usa PHP5 encara és molt dolent doncs bé amb això podrem saber fins a quin punt ho és.

  • Object handles
  • Better constructors (uniform name, changing $this not allowed)
  • Destructors now exist
  • Visibility (public, protected, private for methods and attributes)
  • Exceptions (an alternative to triggering errors using the new try{} catch{} syntax)
  • Classconstants (defines using the class for a name space)
  • Reflection (dynamic examination of classes, methods and arguments)
  • Type hinting (specifying expected classes or interfaces for method arguments)

També hi podem trobar altres novetats una mica menys conegudes:

  • New magic methods (__get() and __set() allow you to control attribute access; __call() lets you dynamically intercept all method calls to the object; __sleep() and __wakeup() let you override serialization behavior; and __toString() lets you control how an object represents itself when cast as a string)
  • Autoloading (allows the end user to try to automatically load the class the first time a reference to it is made)
  • Final (do not allow a method or a class to be overridden by subclasses)

A més hi ha coses com la part d’object handles que donen molt de si:

  • Create an object by reference, as in $obj =& new Class;
  • Pass an object by reference, like function funct(&$obj_param) {}
  • Catch an object by reference function &some_funct() {} $returned_obj =&
    some_funct()

En escència el que més m’ha agradat ho teniu resumit aquí, ja sé que esta en anglès però em feia una mandra brutal traduir-ho. Si m’animo un dia d’aquests donaré més detalls de com aprofitar aquestes avantatges per implementar design patterns amb PHP5. Realment ja comences a sentir-te com un programador de veritat quan veus que el PHP5 no té cap problema en suportar estructures que fins ara li quedaben tan lluny.

PHP5 – Generant WSDL amb Zend Studio 5.1

Reading time: 3 – 5 minutes

Al programar un webservice amb el PHP5 és més que trivial tal com podem llegir a la documentació sobre SOAP (local) del propi PHP. El problema ve quan volent aprofitar la simplicitat dels serveis SOAP toca programar a mà el WSDL. O sigui, agafa i posat a definir la interficie en XML de la/es classe/s que vols exportar a través del webservice, o sigui, una missión imposible.

La meva sorpresa ha estat veure que després d’adpotar el Zend Studio com a IDE de programació del meu codi PHP he vist que disposava d’un assistent ben senzill d’usar per tal de generar automàticament aquest fitxer WSDL. La cosa és ben senzilla imaginem que usem el codi de l’exemple de la web de Zend, com comentava abans.

El servidor SOAP:

<?php
class QuoteService {
  private $quotes = array("ibm" => 98.42);
	function getQuote($symbol) {
    if (isset($this->quotes[$symbol])) {
      return $this->quotes[$symbol];
    } else {
      throw new SoapFault("Server","Unknown Symbol '$symbol'.");
    }
  }
}
	$server = new SoapServer("server2.wsdl");
$server->setClass("QuoteService");
$server->handle();
?>

El client, encara més simple que el servidor:

<?php
  $client = new SoapClient("server2.wsdl");
  print($client->getQuote("ibm"));
?>

Ara que ja tenim el codi en el nostre Zend, només cal que anem a:

menu.png

Cal seguir l’assistent que no és massa difícil, aquí en teniu els passos capturats per l’exemple del que parlem:

wizard-wsdl-1.png
wizard-wsdl-2.png

Podeu veure com s’exporten automàticament les classes dels arxius que seleccioneu, cal que poseu al costat de cada classe exportada la URL a través de la qual s’accedeix al servei:

wizard-wsdl-3.png

Al final obtenim el fitxer WSDL, en el nostre cas aquest:

<?xml version='1.0' encoding='UTF-8'?>
	<!-- WSDL file generated by Zend Studio. -->
	<definitions name="server2" targetNamespace="urn:server2" xmlns:typens="urn:server2" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/" xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://schemas.xmlsoap.org/wsdl/">
	<message name="getQuote">
		<part name="symbol"/>
	</message>
	<message name="getQuoteResponse">
		<part name="getQuoteReturn"/>
	</message>
	<portType name="QuoteServicePortType">
		<operation name="getQuote">
			<input message="typens:getQuote"/>
			<output message="typens:getQuoteResponse"/>
		</operation>
	</portType>
	<binding name="QuoteServiceBinding" type="typens:QuoteServicePortType">
		<soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http"/>
		<operation name="getQuote">
			<soap:operation soapAction="urn:QuoteServiceAction"/>
			<input>
				<soap:body namespace="urn:server2" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
			</input>
			<output>
				<soap:body namespace="urn:server2" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"/>
			</output>
		</operation>
	</binding>
	<service name="server2Service">
		<port name="QuoteServicePort" binding="typens:QuoteServiceBinding">
			<soap:address location="http://oriol.joor.net/soap/server2.php"/>
		</port>
	</service>
</definitions>

Si sou observadors notareu que aquest fitxer és lleugerament diferent al de la documentació que mostra Zend. Però jo l’he provat i funciona perfectament així doncs no m’hi trencaré el cap en saber a què es deuen aquests petits canvis al implmentar aquest format XML.

…i 1000!!!

Reading time: < 1 minute

Doncs després de més de 5 anys escribint al meu blog, ús informo que aquest és el post 1.000, per fi! hi ha molta gent que amb menys d’1 any de blog ja n’ha escrit més que jo de posts. Però bé suposo que el merit d’aquest blog no és el número d’articles sinó el temps que fa que els estic escribint 🙂

Aprofitant aquest motiu de celebració, també us informo que estreno verisó del blogcms, que no heu notat res, ja ho sé… hi hi hi! només he actualitzat el motor del sistema. A més també us informo que ara esta corrent amb un PHP 5.1.2 i no amb un PHP 4 com fins ara. Tinc intenció d’aprofundí molt més amb la programació orientada a objectes en PHP. Ja anireu tenint notícies del tema.

GTK i PHP

Reading time: 1 – 2 minutes

Em sembla que va ser l’Oriol que un dia em va parlar sobre programar aplicacions PHP que usen les llibreries GTK, amb tot el que això implica. O sigui, poder programar aplicacions d’escriptori en llenguatge PHP. Si sabeu programar en PHP us recomano que li doneu un cop d’ull ja veureu com en un moment sou capaços de fer miracles fora del navegador. Us sortiràn unes GUIs que no us creureu que les heu fet voslatres i menys en PHP. A més del phpGTK hi ha una eina que es diu gnope que ens permet fer fins hi tot instal·ladors de les eines que programeu, tan per Win, Linux i Mac OS X. La veritat és que a mi la idea m’ha encantat.

deployment.gif

MVC i PHP

Reading time: 4 – 7 minutes

Com molts sabeu jo no sóc informàtic ni pretenc ser-ho, ara com jo sempre dic, als telemàtics se’ns pre-suposa que sabem informàtica. Alguns diuen que saber programar no és saber informàtica però jo crec que almenys si saps programar algo d’infomàtica saps. Així doncs entre tot aquest dilèma que m’he montat per dir només que, fins no fa massa anys no havia sentit a parlar del sistema de programació MVC (Model Business, View i Controller). Potser algú recorda que fa molt de temps vaig publicar un article on recomanava la web d’en Tony Marston. Doncs aquí van ser on per primer cop vaig coneixer una mica a fons tot aquest tema.

Malgrat no ho necessito per res en especial fa uns dies vaig pensar que seria bona idea aprofundir una mica més en aquest tema del MVC i he estat llegint una miqueta sobre el tema. Com que el llenguatge de programació que més uso és el PHP vaig buscar informació de frameWorks que implementessin el model MVC sobre aquest llenguatge que en principi no implementa per defecta una estructura MVC. Perquè us feu una idea en aplicacions ASP (Applications Service Provider) el sistema MVC per excel·lència és els servlets de Java, per exemple, la implementació Tomcat. Pels que conegueu millor el tema que jo és el que en java en diuen struts. Si algú de vosaltres ja ho coneix i vol una implementació dels mateixos feta en PHP us recomano que us mireu el phpMVC.

Com us comentava abans tot això ho vaig descobrir a fons a través d’en Tony i ell mateix té un document que crec que és molt bo, que explica com implementar un model MVC directament sobre PHP sense passar per un frameWork concret. El document en qüestió es diu The Model-View-Controller (MVC) Design Pattern for PHP. Si com jo abans d’atacar documents com aquest heu de fer una intro al tema, la documentació de Java sobre el MVC i els struts jo diria que és molt bona. Concretament us recomano els següents capitols:

Un bon dibuix perquè veieu pels que no us soni de res el que dic, que el model és molt útil:

web-tier8.gif

Des de la documentació d’Oracle sobre els models MVC he trobat un gràfic que aplica la teoria exposada en el gràfic i documents anteriors des d’un gràfic aplicat directament a explicar les sigles MVC:

mvc.jpg

Tornant al tema PHP hi ha molts més frameworks i webs que parlen d’MVC sobre aquest llenguatge. Però potser els que més bona pinta m’han fet, sense haver tingut la sort de poder-los provar amb calma i tranquil·litat, són els que us poso a continuació:

  • phpMVC com us he comentat abans jo diria que és un dels frameworks que implementen MVC més complerts, sobretot perquè en la capa d’accés a dades i en la capa de presentació suporta llibreries tan conegudes com: PEAR, phpLIB, Smarty i moltes d’altres. Com us he comentat és una implementació directa del model struts que usen els servlets de java.
  • cakePHP jo diria que és la llibreria MVC perfecte per programar ràpidament una aplciació sense tenir una curva d’aprenentatge que es dilati massa en el temps.
  • WACT (Web Application Component Toolkit) també té pinta de no ser massa complicat i jo diria que esta prou bé. Sembla que esta pensat perquè no ens perdem a l’hora de programar aplicacions segures. Però no veig massa clar quines carències té. Potser la petita comunitat d’usuaris?

Com que sobre aquest tema no en sé gaire més, us remeto a una discusió que he trobat en un forum que sembla prou interessant i de nivell. A més molta gent hi parla amb coneixement de causa, cosa que és d’agraïr, Tired of non-standards? Take a look. si aquesta us sembla poc concreta, una altre: PHP Frameworks.

Si algún dels lectors que sigui informàtic, o que senzillament, en sapigue molt més que jo i ens pot donar eines per mortals per dominar aquestes tècniques encantat de mirarme-les.

Treballant amb cookies de sessió i PHP

Reading time: 1 – 2 minutes

A vegades necessitem parlar amb una web des de PHP i aquesta usa cookies de sessió sense les quals no podem parlar amb la web. Per agafar la cookie d’inici de sessió podem usar aquesta funció:

function getgaleta($server, $port)
{
   $cont = "";
   $ip = gethostbyname($server);
   $fp = fsockopen($ip, $port);
   if (!$fp)
   {
       return "Unknown";
   }
   else
   {
       $com = "GET http://www.barcelonastyle.com/gc/web/webesp/framesetxsl.asp HTTP/1.0rnrn";
       fputs($fp, $com);
       while (!feof($fp))
       {
           $cont .= fread($fp, 500);
       }
       fclose($fp);
       return substr($cont, strpos($cont, "Set-Cookie: ")+12, 45);
   }
}

Si ara que ja tenim la cookie el que volem fer és usar-la per fer peticions contra el site, podem usar aquesta altre funció:

function getcontent($server, $port, $file,$galeta)
{
   $cont = "";
   $ip = gethostbyname($server);
   $fp = fsockopen($ip, $port);
   if (!$fp)
   {
       return "Unknown";
   }
   else
   {
       $com = "GET http://".$server.$file." HTTP/1.0rnCookie:".$galeta."rnrn";
       fputs($fp, $com);
       while (!feof($fp))
       {
           $cont .= fread($fp, 500);
       }
       fclose($fp);
       return $cont;
   }
}

Tonto però útil, tinc moltíssimes més funcions però tampoc és qüestió de marejar, només que les he trobat útils aquestes junt amb les dues anteriors.