Follow Us on Twitter

Oracle en PHP

Gepubliceerd in

Juli 2007 - Oracle ondersteunt de vrijheid van keuze, flexibiliteit en lagere kosten voor (eind)gebruikers. Door ondersteuning van open source technieken als Linux, Apache en PHP biedt Oracle dus ook open source oplossingen voor ontwikkeling.

Linux en Apache zijn al langer bekende voorbeelden van open source oplossingen in combinatie met Oracle. PHP nog niet. Tijd dus om eens nader in te gaan op deze scripting taal en te laten zien wat er allemaal mogelijk is met Oracle en PHP.

Is PHP nu een volwaardig alternatief voor bijvoorbeeld ADF of Apex om een applicatie mee te ontwikkelen?

Wat is PHP?

PHP is een open source server side scripting taal. PHP is een afkorting van PHP: Hypertext Preprocessor en is een van de meest populaire Web applicatie scripting talen ter wereld. PHP is in 1995 ontworpen door Rasmus Lerdorf. PHP is afgeleid van Perl. PHP wordt op de server uitgevoerd en geeft als output HTML code. Dit biedt vele voordelen. Zo zal een gebruiker nooit de broncode kunnen zien want hij of zij ziet alleen maar de HTML code. De HTML output kan dynamisch worden samengesteld, dus een php-script kan afhankelijk van data een compleet andere webpagina laten zien.

PHP is beschikbaar op nagenoeg elk platform en voor de belangrijkste webservers maar wordt vaak in een adem genoemd met Linux, Apache en MySQL, de zogenaamde LAMP. Met deze vier componenten is het mogelijk om een open source website te bouwen. Linux als besturingssysteem, Apache voor de webserver, MYSQL als de database en PHP als de taal om de webpagina's in te maken. Maar PHP ondersteunt toegang tot bijna elke database en kan dus ook gebruik maken van een Oracle database (inclusief features zoals stored procedures). We gaan daarom in dit Whitebook laten zien hoe een Oracle database vanuit PHP is te benaderen en hoe data op te halen of te inserten, updaten of deleten.

PHP code kan gewoon met een simpele teksteditor gemaakt worden. Er zijn ook specifieke PHP-editors die standaard code voorhanden hebben om bijvoorbeeld een HTML table te maken. Dit bespaart een hoop typewerk.

PHP code kan in een PHP-script of in een HTML-script worden opgenomen. Dus zowel bestanden met de extensie .HTML, .HTM of .PHP. Dit moet echter wel op de server ingesteld worden. Een groot voordeel is dat PHP en HTML door elkaar heen gebruikt kunnen worden. Ongeacht de extensie, PHP code begint altijd met:

<?php

en eindigt met:

?>

Wat kan er allemaal met PHP en Oracle?

In PHP kunnen op de Oracle database alle DML- en DDL-statements uitgevoerd worden. Met Oracle en PHP is het onder andere mogelijk om een webservice te bouwen, een pdf document te creëren en ajax functionaliteit in te bouwen. Omdat PHP open source is, is er ook veel over te vinden op internet en is er voor nagenoeg ieder probleem wel een oplossing bedacht. En er zijn genoeg tutorials te vinden zodat PHP gemakkelijk te leren is.

Omgeving inrichten

Vanuit de webpagina die de gebruiker ziet wordt er een connectie met de database gemaakt volgens onderstaand schema:

Zoals uit dit plaatje blijkt moet er in ieder geval een webserver aanwezig zijn en PHP vanaf versie 4. En natuurlijk ook nog een Oracle database. In dit voorbeeld gaan we uit van een Apache webserver en een Oracle Express Edition database.

Er zijn meerdere manieren om een omgeving in te richten om het mogelijk te maken om vanuit PHP een Oracle database te benaderen: aparte installaties van de verschillende componenten of, kant en klaar, de Zend Core for Oracle. In dit whitebook wordt alleen de installatie voor Windows beschreven.

Mogelijkheid 1

Apache en PHP en Oracle zijn apart geinstalleerd. Zorg dat Apache php files kan lezen door in de httpd.conf de volgende regels op te nemen:

AddType application/x-httpd-php .php
PHPIniDir "C:PHP

Waarbij er wordt uitgegaan van een php installatie in C:PHP. httpd.conf is te vinden in de directory conf onder de apache home directory.

Download de module php_oci8.dll. Deze is te downloaden via http://pecl4win.php.net/ext.php/php_oci8.dll. Kopieer deze module naar de c:phpextensions directory

Pas vervolgens het bestand php.ini aan. Verwijder de puntkomma (;) voor de volgende regel:

;extension=php_oci8.dll

Herstart tenslotte de Apache webserver.

Mogelijkheid 2

Installeer op de host Zend Core voor Oracle. Zend is de maker van de Zend Core, een omgeving die het mogelijk maakt om php scripts uit te voeren op de server. Het makkelijke hiervan is dat na installatie van Zend Core alles meteen werkt. Dus er hoeven niet nog eens allerlei instellingen veranderd te worden. Zend Core voor Oracle is in feite de php omgeving op de host waarbij Zend al de belangrijkste instellingen heeft gedaan, inclusief de Apache webserver. Dus na installatie is het mogelijk om php-scripts op de host te draaien die een connectie met de Oracle database kunnen maken.

Connectie met Oracle

Er wordt bij voorkeur gebruik gemaakt van de OCI extension module om in een php script te connecten met Oracle. Deze module is geoptimaliseerd voor Oracle en biedt veel opties.

Een connectie maken met de database gaat met behulp van de functie OCILogon waarbij als parameters de logon parameters user, password en connect string worden meegegeven.

De code voor de connectie met de database:

<?php 
  $c1=OCILogon("demo", "demo_pwd", "XE"); 
  if ( ! $c1 ) 
  { 
    echo "Unable to connect: " . var_dump( OCIError() );
    die(); 
  } 
?> 

Eventueel kunnen nog de Oracle environment variabelen gezet worden. Dit moet dan wel voor de connect gebeuren:

<?php 
  PutEnv("ORACLE_SID=ORCL");
  PutEnv("TNS_ADMIN=/var/opt/oracle"); 
  // 
  $c1=OCILogon("demo", "demo_pwd", null); 
  if ( ! $c1 )
  {
    echo "Unable to connect: " . var_dump( OCIError() ); 
    die(); 
  }
?>

Het is zelfs mogelijk om de complete inhoud van de TNSNAMES.ORA in het PHP-script op te nemen. Omwille van onderhoudbaarheid is dit echter niet aan te raden.

Select statements

Het selecteren van data gaat met behulp van de functies OCIParse, OCIExecute en OCIFetch. Eerst wordt de query opgegeven met OCIParse. Vervolgens wordt de query uitgevoerd met OCIExecute. Met OCIFetch worden de resultaten daadwerkelijk naar variabelen gekopieerd. Hierbij kunnen gewoon de kolomnamen van de tabel gebruikt worden.

Select statements:

$s1 = OCIParse($c1, "select * from departments");
OCIExecute($s1, OCI_DEFAULT);
while (OCIFetch($s1)) 
{
  $l_id1       = ociresult($s1, "ID");
  $l_name1     = ociresult($s1, "NAME");
  $l_location1 = ociresult($s1, "LOCATION");
  echo "$l_id1" . ' ' . "$l_name1" . ' ' . "$l_location1";
 }

DML statements

DML statements worden uitgevoerd met behulp van de functies OCIParse en OCIExecute. Eerst wordt het DML statement opgegeven met OCIParse en vervolgens met behulp van de functie OCIExecute daadwerkelijk uitgevoerd.

Voorbeelden:

// Insert voorbeeld
$s = OCIParse($c, "insert into departments values (40, 'IT','BOSTON')");
OCIExecute($s, OCI_DEFAULT);
// Update voorbeeld
$s = OCIParse($c, "update departments set location = 'SAN FRANCISCO'");
OCIExecute($s, OCI_DEFAULT);

Bind variabelen

Select- en DML-statements kunnen ook via bind variabelen gegeven worden. Dit heeft als voordeel dat in het begin van het script de statements opgenomen kunnen worden en verderop in het script de daadwerkelijke selects, inserts, updates of deletes. Dit maakt de code overzichtelijker en meer onderhoudbaar. Verder is het gebruik van bind variabelen goed voor de performance want bij gelijke queries wordt in geval van bind variabelen slechts 1 query in de database cache bewaard. Zie de afbeeldingen hieronder met als voorbeeld een select statement.

Zonder bind variabelen:

Met bind variabelen:

Code voorbeelden:

// Select met bind variabelen
$s1 = OCIParse($c1, "select * from departments where id = :bind1");
$var1 = 40;
OCIBindByName($sl, ":bind1", $var1);
OCIExecute($s1, OCI_DEFAULT);
while (OCIFetch($s1)) 
{
  $l_id1       = ociresult($s1, "ID");
  $l_name1     = ociresult($s1, "NAME");
  $l_location1 = ociresult($s1, "LOCATION");
  echo "$l_id1" . ' ' . "$l_name1" . ' ' . "$l_location1";
 }
// Insert met bind variabelen
$var1 = 40;
$var2 = "IT";
$var3 = "LOS ANGELES";
$s = OCIParse($c, "insert into departments values (:bind1,:bind2,:bind3)");
OCIBindByName($s, ":bind1", $var1);
OCIBindByName($s, ":bind2", $var2);
OCIBindByName($s, ":bind3", $var3);
OCIExecute($s, OCI_DEFAULT);

Stored procedures

PHP ondersteunt ook het gebruik van stored procedures. Stored procedures kunnen aangemaakt worden in een PHP-script:

<?php
  // Connect
  $c=OCILogon("demo", "demo_pwd", "XE");
  if ( ! $c ) {
     echo "Unable to connect: " . var_dump( OCIError() );
     die();
  }

  // Database procedure aanmaken
  $s = OCIParse($c, "create procedure proc1(p1 IN number,p2 OUT number)" .
                    " as " .
                    "begin" .
                    "  p2 := p1 + 10;" .
                    "end;");
  OCIExecute($s, OCI_DEFAULT);
  
 if ($s) 
  { 
    echo “Procedure aangemaakt”; 
  }

?>

Uiteraard kan de procedure ook gewoon in SQLplus of in een IDE-tool aangemaakt worden. Het aanroepen in PHP gebeurt als volgt:

<php
  // Database procedure aanroepen
  $in_var = 10;
  $s = OCIParse($c, "begin proc1(:bind1, :bind2); end;");
  OCIBindByName($s, ":bind1", $in_var);
  OCIBindByName($s, ":bind2", $out_var, 32); // out variabele max. 32 lang
  OCIExecute($s, OCI_DEFAULT);
  echo "Bij een inputwrde " . $in_var . "geeft de procedure " .
      $out_var . " terug.";

  // Uitloggen
  OCILogoff($c);
?>

Commit en rollback

Het committen van data gebeurt met de functie OCIcommit. Rollback kan gegeven worden met de functie OCIRollback.

Voorbeelden:

// geef commit
OCICommit($c);
// geef rollback;
OCIRollback($c);

Let op: met de functie OCIExecute kan aangegeven worden of een statement direct gecommit moet worden of niet. Dat gebeurt middels de tweede parameter. In de voorbeelden hierboven staat OCI_DEFAULT, wat betekent dat er niet meteen gecommit wordt. Gebruik OCI_COMMIT_ON_SUCCESS om direct te committen nadat het statement succesvol is uitgevoerd. De laatste is ook de default waarde. Bij het gebruik van OCI_DEFAULT wordt er aan het einde van het script een impliciete commit gedaan als er niet specifiek een commit of rollback is gegeven. Dit is overigens standaard SQLplus functionaliteit.

Commit en rollback

Het committen van data gebeurt met de functie OCIcommit. Rollback kan gegeven worden met de functie OCIRollback.

Voorbeelden:

// geef commit
OCICommit($c);
// geef rollback;
OCIRollback($c);

Let op: met de functie OCIExecute kan aangegeven worden of een statement direct gecommit moet worden of niet. Dat gebeurt middels de tweede parameter. In de voorbeelden hierboven staat OCI_DEFAULT, wat betekent dat er niet meteen gecommit wordt. Gebruik OCI_COMMIT_ON_SUCCESS om direct te committen nadat het statement succesvol is uitgevoerd. De laatste is ook de default waarde. Bij het gebruik van OCI_DEFAULT wordt er aan het einde van het script een impliciete commit gedaan als er niet specifiek een commit of rollback is gegeven. Dit is overigens standaard SQLplus functionaliteit.

Uitloggen

Als het script beëindigd is wordt automatisch de verbinding met de Oracle database verbroken. De functie OCILogoff heeft dus weinig nut. Echter, mochten er problemen zijn met sessies die om een of andere reden toch open blijven dan kan met deze functie de sessie alsnog beëindigd woden.

<?php
  OCILogoff($c1);
?>

PHP ontwikkeltools

PHP scripts zijn gemakkelijk te bewerken in Notepad of iedere andere teksteditor. Er zijn echter speciale ontwikkeltools voor PHP op de markt. Zend heeft ook een ontwikkeltool gemaakt om php code in te ontwikkelen. Het heet Zend Studio en biedt mogelijkheden als debugging, live preview en diverse edit opties om de code duidelijker en leesbaarder te maken. Verder biedt het tool voorgedefinieerde templates en voorbeeldcodes voor de meest gebruikte functies in HTML en PHP. Om bijvoorbeeld een HTML tabel te maken hoeft alleen maar het aantal kolommen en rijen opgegeven te worden en Zend Studio maakt dan de PHP code. Tezamen met Zend Studio is ook Zend Guard te downloaden. Dit is een soort versiebeheertool. Tenslotte is er nog het Zend framework welke ondersteuning biedt voor de meest voorkomende dingen op webpagina´s, zoals onder andere pdf-files aanmaken, mailfunctionaliteit, webservices en zoeken van data.

Oracle heeft zelf een plugin beschikbaar voor Jdeveloper zodat ook in deze tool PHP-scripts geschreven en getest kunnen worden.

XAJAX

In een PHP script kan ook gebruikt worden gemaakt van Ajax, de techniek om in een webpagina dynamisch data te verversen zonder dat de hele pagina opnieuw geladen hoeft te worden. Hier is een open-source module voor beschikbaar en heet xajax.

Onderstaand voorbeeld geeft de kracht van Ajax weer. Hier wordt namelijk dynamisch data uit een tabel getoond welke iedere 5 seconden wordt ververst. Als iemand nu vanaf bijvoorbeeld de sqlplus prompt een update doet op deze tabel zal deze wijziging automatisch worden getoond.

Het script begint met een function welke in de HTML-output als javascript function wordt weergegeven. In deze function wordt een connectie gemaakt met de Oracle database en een select gedaan op de tabel. Vervolgens worden de resultaten in een table getoond. Dit alles met behulp van HTML tags. Vervolgens wordt de rest van de pagina opgebouwd en wordt er een javascript timer gemaakt die elke 5 seconden afloopt en bij het aflopen de function aanroept zodat dan de meest recente data wordt opgehaald en getoond.

<?php
/*
|| Oracle - PHP connection en select voorbeeld
*/
require ('xajax.inc.php');

function oracle_functie() 
{
  $l_output = "";

  // Connect
  $c1=OCILogon("demo", "demo_pwd", null);
  if ( ! $c1 ) 
  {
    echo "Unable to connect: " . var_dump( OCIError() );
    die();
  }

  // Bouw de html table op met de data
  $l_output = $l_output . '<div align="center">';
  $l_output = $l_outupt . '<h1>Oracle xajax voorbeeld</h1>';
  $l_output = $l_output . '<table border="1">';
  $l_output = $l_output . '</tr>';
  $l_output = $l_output . '<td>ID</td>';
  $l_output = $l_output . '<td>Afdeling</td>';
  $l_output = $l_output . '<td>Locatie</td>';
  $l_output = $l_output . '</tr>';

  // Select statement
  $s1 = OCIParse($c1, "select * from departments");
  OCIExecute($s1, OCI_DEFAULT);

  // Vul de html table
  while (OCIFetch($s1)) 
  {
    $l_id1       = ociresult($s1, "ID");
    $l_name1     = ociresult($s1, "NAME");
    $l_location1 = ociresult($s1, "LOCATION");

    $l_output = $l_output . '<tr>';
    $l_output = $l_output . '<td>' . $l_id1 . '</td>';
    $l_output = $l_output . '<td>' . $l_name1 . '</td>';
    $l_output = $l_output . '<td>' . $l_location1 . '</td>';
    $l_output = $l_output . '</tr>';

    //$l_output = $l_output . "nn";
  }

  // Uitloggen
  OCILogoff($c1);

  $objResponse = new xajaxResponse();
  $objResponse->addAssign("db_veld","innerHTML",$l_output);
	
  return $objResponse;

}

// Xajax socket aanmaken
$xajax = new xajax(); 

$xajax->registerFunction("oracle_functie");

$xajax->processRequests();

// Laat de head tags zien
echo"<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" 
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">"; echo"<html>"; echo"<head>"; // output de xajax javascript. Dit moet
// aangeroepen worden tussen de head tags $xajax->printJavascript('../'); // Javascriptje om een timer aan te maken echo"<script type="text/javascript">"; echo" var t; "; echo " function timedCount() "; echo " {xajax_oracle_functie(); t=setTimeout("timedCount()",5000);} "; echo "</script>"; echo"</head>"; echo"<body>"; echo"<div align="center" id="db_veld"> </div>"; echo"<script type="text/javascript">"; echo " timedCount() "; echo "</script>"; echo"</body>"; echo"</html>"; // Uitloggen OCILogoff($c); ?>

Conclusie

Oracle en PHP gaan prima samen als het gaat om het maken van een webapplicatie met een Oracle database. Het vereist wel veel typewerk om een fatsoenlijke applicatie te bouwen met afwijkende functionaliteit. Eenmaal de basics geleerd is het simpel om in PHP te programmeren. Er is veel over te vinden op internet en de OCI8 module biedt voldoende flexibiliteit om ook in PHP volledig gebruik te maken van de Oracle functionaliteiten.

Waar ADF een strikte scheiding heeft tussen de verschillende lagen kent PHP geen enkele scheiding. Daardoor is de onderhoudbaarheid van een PHP script minder groot. Daar staat tegenover dat er minder nodig is om een ontwikkelomgeving op te zetten. PHP scripts kunnen immers geschreven worden in simpele teksteditors, terwijl voor ontwikkelen met ADF JDeveloper benodigd is.

PHP is vooral interessant als er tegen geringe kosten in korte tijd en met weinig middelen een applicatie gerealiseerd moet worden. Functies als webservices en het genereren van een PDF bestand en technieken als Ajax zijn relatief gemakkelijk te realiseren in PHP. In combinatie met Zend Studio en Zend framework biedt PHP dus een prima alternatief voor ontwikkeling met ADF of Apex.

Referenties

 
Over de auteur
Marcel van der Plas is Oracle consultant bij Whitehorses een heeft ruim 10 jaar ervaring als Oracle ontwikkelaar. Hij heeft voornamelijk ervaring met Designer, Forms en PL/SQL. Zowel privé als zakelijk is hij geïnteresseerd in webtechnologie en de uitgbreide mogelijkheden van PHP.

Waardering:
 
Tags:

Reacties

Nieuwe reactie inzenden

De inhoud van dit veld is privé en zal niet openbaar worden gemaakt.

Meer informatie over formaatmogelijkheden

CAPTCHA
Deze vraag is om te testen of u een persoon bent en om spam te voorkomen
Image CAPTCHA
Enter the characters shown in the image.