SlideShare uma empresa Scribd logo
1 de 102
An Introduction to pl/php



             by Robert   Treat
             http://www.brighterlamp.org/
What is pl/php
    aka PL/PHP, Pl/PHP, pl/PHP
●




    Database procedural language based on
●


    PHP

    Allows you to program inside the database
●


    using PHP
Let's see an example eh?
CREATE OR REPLACE FUNCTION hello_world()
RETURNS text
LANGUAGE plphp
AS $$
 $var = quot;howdy yallquot;;
 RETURN $var;
$$;
Let's see an example eh?
CREATE OR REPLACE FUNCTION hello_world()
RETURNS text
LANGUAGE plphp
AS $$
 $var = quot;howdy yallquot;;
 RETURN $var;
$$;
          pagila=# select hello_world();
           hello_world
          ----------------
           howdy yall
          (1 row)
Let's see an example eh?
CREATE OR REPLACE FUNCTION hello_world()
RETURNS text
LANGUAGE plphp
AS $$
 $var = quot;howdy yallquot;;
 RETURN $var;
$$;
          pagila=# select hello_world();
           hello_world
          ----------------
           howdy yall
          (1 row)
                 Fancy huh?
Where does pl/php come from?
    Originally developed by Command Prompt, Inc.
●




    Currently maintained by Alvaro Herrera, Alexey
●


    Klyukin (both work for Command Prompt)
    Has gone through a number of re-writes
●



    http://plphp.commandprompt.com/
●
Who uses pl/php?
    We don't know... but it seems popular...
●
Who uses pl/php?
Who uses pl/php?
So why do people use pl/php?
     Nicely integrates with PostgreSQL
 ●



         close to data
     –

         easily access tables and whatnot
     –
So why do people use pl/php?
     Nicely integrates with PostgreSQL
 ●



         close to data
     –

         easily access tables and whatnot
     –


     Save on network traffic
 ●
So why do people use pl/php?
     Nicely integrates with PostgreSQL
 ●



         close to data
     –

         easily access tables and whatnot
     –


     Save on network traffic
 ●




     You can use PHP to write it!
 ●
Any reason to avoid it?
    PostgreSQL specific
●
Any reason to avoid it?
    PostgreSQL specific (well, maybe that's really
●


    a reason to use it)
Any reason to avoid it?
    PostgreSQL specific (well, maybe that's really
●


    a reason to use it)
    Adds dependencies to your database
●




    Code is still green
●




    Small user community
●
Installation
    Pre-requisites:
●


        PostgreSQL 8.1+
    –
Installation
    Pre-requisites:
●


        PostgreSQL 8.1+
    –

                  -bash-3.00$ pg_config --version
Installation
    Pre-requisites:
●


        PostgreSQL 8.1+
    –

                  -bash-3.00$ pg_config --version
                  PostgreSQL 8.1.9
Installation
    Pre-requisites:
●


        PostgreSQL 8.1+
    –

                   -bash-3.00$ pg_config --version
                   PostgreSQL 8.1.9

        Also need php development package (yum install
    –
        php-devel)
Installation
    Pre-requisites:
●


        PostgreSQL 8.1+
    –

                    -bash-3.00$ pg_config --version
                    PostgreSQL 8.1.9

        Also need php development package (yum install
    –
        php-devel)

               [root@localhost html]# php-config --version
Installation
    Pre-requisites:
●


        PostgreSQL 8.1+
    –

                    -bash-3.00$ pg_config --version
                    PostgreSQL 8.1.9

        Also need php development package (yum install
    –
        php-devel)

               [root@localhost html]# php-config --version
               5.1.2
Installation
    Grab the latest release tarball, unpack it, configure
●


    and make (simple eh?)
Installation
        Grab the latest release tarball, unpack it, configure
    ●


        and make (simple eh?)
rob@ridley:~/devel/plphp$
Installation
        Grab the latest release tarball, unpack it, configure
    ●


        and make (simple eh?)
rob@ridley:~/devel/plphp$ tar zxvf plphp-1.3.3.tar.gz
Installation
        Grab the latest release tarball, unpack it, configure
    ●


        and make (simple eh?)
rob@ridley:~/devel/plphp$ tar zxvf plphp-1.3.3.tar.gz
./plphp-1.3.3/
./plphp-1.3.3/sql/
<snip>
./plphp-1.3.3/plphp.c
rob@ridley:~/devel/plphp$
Installation
        Grab the latest release tarball, unpack it, configure
    ●


        and make (simple eh?)
rob@ridley:~/devel/plphp$ tar zxvf plphp-1.3.3.tar.gz
./plphp-1.3.3/
./plphp-1.3.3/sql/
<snip>
./plphp-1.3.3/plphp.c
rob@ridley:~/devel/plphp$ cd plphp-1.3.3
Installation
        Grab the latest release tarball, unpack it, configure
    ●


        and make (simple eh?)
rob@ridley:~/devel/plphp$ tar zxvf plphp-1.3.3.tar.gz
./plphp-1.3.3/
./plphp-1.3.3/sql/
<snip>
./plphp-1.3.3/plphp.c
rob@ridley:~/devel/plphp$ cd plphp-1.3.3
rob@ridley:~/devel/plphp/plphp-1.3.3$
Installation
        Grab the latest release tarball, unpack it, configure
    ●


        and make (simple eh?)
rob@ridley:~/devel/plphp$ tar zxvf plphp-1.3.3.tar.gz
./plphp-1.3.3/
./plphp-1.3.3/sql/
<snip>
./plphp-1.3.3/plphp.c
rob@ridley:~/devel/plphp$ cd plphp-1.3.3
rob@ridley:~/devel/plphp/plphp-1.3.3$ ./configure
Installation
        Grab the latest release tarball, unpack it, configure
    ●


        and make (simple eh?)
rob@ridley:~/devel/plphp$ tar zxvf plphp-1.3.3.tar.gz
./plphp-1.3.3/
./plphp-1.3.3/sql/
<snip>
./plphp-1.3.3/plphp.c
rob@ridley:~/devel/plphp$ cd plphp-1.3.3
rob@ridley:~/devel/plphp/plphp-1.3.3$ ./configure
checking for gcc... gcc
<snip>
checking for pg_config... /usr/bin/pg_config
checking for existence of /usr/lib/postgresql/8.1/lib/pgxs/src/makefiles/pgxs.mk... yes
checking for PostgreSQL version... 8.1.9
checking for php-config... /usr/bin/php-config
checking for php_module_startup in -lphp5... no
checking for php_module_startup in -lphp4... no
configure: error: Cannot locate a proper php library
Installation – libphp5

    no longer supports building against mod_php
●



    most distributions don't ship static php library
●



    don't be fooled!
●


         rob@ridley:~$ locate libphp
     ●
         /usr/lib/libphp5.so
         /usr/lib/apache2/modules/libphp5.so

         rob@ridley:~$ ls ­al /usr/lib/libphp5.so
         lrwxrwxrwx 1 root root 35 2006­08­26 20:43 
         /usr/lib/libphp5.so ­> /usr/lib/apache2/modules/libphp5.so
Installation – libphp5

    no longer supports building against mod_php
●



    most distributions don't ship static php library
●



    need to build your own php libs
●



          make libphp5.la install
      ●



          configure –enable-embed –prefix=your_dir;
      ●


          make install
Installation
      configure plphp
  ●



                                        ./configure –with-php=/home/rob/devel/plphp/embedphp/
rob@ridley:~/devel/plphp/plphp-1.3.3$
checking for gcc... gcc
<snip>
checking for pg_config... /usr/bin/pg_config
checking for existence of /usr/lib/postgresql/8.1/lib/pgxs/src/makefiles/pgxs.mk... yes
checking for PostgreSQL version... 8.1.9
checking for php-config... /home/rob/devel/plphp/embedphp//bin/php-config
checking for php_module_startup in -lphp5... yes
configure: creating ./config.status
config.status: creating Makefile
config.status: creating config.h
Installation
     sudo make install
●




    rob@ridley:~/devel/plphp/plphp-1.3.3$ sudo make install
    <snip>
    /bin/sh /usr/lib/postgresql/8.1/lib/pgxs/src/makefiles/../../config/install-sh -c -m 755
    libplphp.so.0.0 /usr/lib/postgresql/8.1/lib/plphp.so
Installing pl/php into the Database
    Once .so is compiled, you need to install the
●


    language into your database.
Installing pl/php into the Database
    Once .so is compiled, you need to install the
●


    language into your database.
    Should be easier than compiling
●
Installing pl/php into the Database
    Once .so is compiled, you need to install the
●


    language into your database.
    Should be easier than compiling
●



    Probably won't be...
●
Installing pl/php into the Database
    pagila=# INSERT INTO pg_pltemplate VALUES
    pagila-# ('plphpu', 'f', 'plphp_call_handler', 'plphp_validator', '$libdir/plphp', NULL);
    INSERT 0 1



     Creates an entry into the shared catalogs
●



     Does not mean that pl/php is installed!
●



     But you can now install it into any database
●


     using the “Create Language” command
Installing pl/php into the Database
pagila=#
Installing pl/php into the Database
pagila=# create language plphp;
Installing pl/php into the Database
pagila=# create language plphpu;
ERROR: could not load library quot;/usr/lib/postgresql/8.1/lib/plphp.soquot;: /usr/lib/libphp5.so:
undefined symbol: ap_loaded_modules
Installing pl/php into the Database
pagila=# create language plphpu;
ERROR: could not load library quot;/usr/lib/postgresql/8.1/lib/plphp.soquot;: /usr/lib/libphp5.so:
undefined symbol: ap_loaded_modules



See? Simple...
Installing pl/php into the Database
pagila=# create language plphp;
ERROR: could not load library quot;/usr/lib/pgsql/plphp.soquot;: libphp5.so: cannot open shared
object file: No such file or directory

See? Simple...


    PostgreSQL can't find the php shared library
●




    We need to find libphp5.so and set
●


    PostgreSQL up to find it.
Installing pl/php into the Database
[root@localhost pgsql]# locate libphp5.so
/usr/lib/httpd/modules/libphp5.so

[root@localhost pgsql]# pg_config --libdir
/usr/lib

[root@localhost pgsql]# ln -sf /usr/lib/httpd/modules/libphp5.so /usr/lib/

[root@localhost pgsql]# createlang -U postgres plphp pagila
CREATE LANGUAGE
Installing pl/php into the Database
  [root@localhost pgsql]# psql -U postgres pagila
  Welcome to psql 8.1.1, the PostgreSQL interactive terminal.

  Type: copyright for distribution terms
      h for help with SQL commands
      ? for help with psql commands
      g or terminate with semicolon to execute query
      q to quit

  pagila=# create language plphpu;
  CREATE LANGUAGE
  pagila=#
pl/php vs. pl/phpu ?
    PostgreSQL offers “trusted” and “untrusted”
●


    languages
    Untrusted means it can access the file system
●



    More flexible, more useful, likely a good
●


    choice when working with any complexity
    Opens small security hole; be aware.
●
pl/php basics
CREATE OR REPLACE FUNCTION iheartphp(text)
RETURNS text
LANGUAGE plphpu
STRICT
AS $$
       $retval = $args[0] . ' loves PHP!';
       return $retval;
$$;
CREATE FUNCTION
pagila=# SELECT iheartphp('Robert');
    iheartphp
-------------------
 Robert loves PHP!
(1 row)

How useful!
pl/php basics
CREATE OR REPLACE FUNCTION iheartphp(text)
RETURNS text
LANGUAGE plphpu
STRICT
AS $$
       $retval = $args[0] . ' loves PHP!';
       return $retval;
$$;
CREATE FUNCTION
pagila=# SELECT iheartphp('Robert');
    iheartphp
-------------------
 Robert loves PHP!
(1 row)

How useful!
pl/php basics
CREATE OR REPLACE FUNCTION iheartphp(text)
RETURNS text
LANGUAGE plphpu
STRICT
AS $$
       $retval = $args[0] . ' loves PHP!';
       return $retval;
$$;
CREATE FUNCTION
pagila=# SELECT iheartphp('Robert');
    iheartphp
-------------------
 Robert loves PHP!
(1 row)

How useful!
pl/php basics
CREATE OR REPLACE FUNCTION iheartphp(text)
RETURNS text
LANGUAGE plphpu
STRICT
AS $$
       $retval = $args[0] . ' loves PHP!';
       return $retval;
$$;
CREATE FUNCTION
pagila=# SELECT iheartphp('Robert');
    iheartphp
-------------------
 Robert loves PHP!
(1 row)

How useful!
pl/php basics
CREATE OR REPLACE FUNCTION iheartphp(text)
RETURNS text
LANGUAGE plphpu
STRICT
AS $$
       $retval = $args[0] . ' loves PHP!';
       return $retval;
$$;
CREATE FUNCTION
pagila=# SELECT iheartphp('Robert');
    iheartphp
-------------------
 Robert loves PHP!
(1 row)

How useful!
pl/php basics
CREATE OR REPLACE FUNCTION iheartphp(text)
RETURNS text
LANGUAGE plphpu
STRICT
AS $$
       $retval = $args[0] . ' loves PHP!';
       return $retval;
$$;
CREATE FUNCTION
pagila=# SELECT iheartphp('Robert');
    iheartphp
-------------------
 Robert loves PHP!
(1 row)

How useful!
pl/php basics
CREATE OR REPLACE FUNCTION iheartphp(text)
RETURNS text
LANGUAGE plphpu
STRICT
AS $$
       $retval = $args[0] . ' loves PHP!';
       return $retval;
$$;
CREATE FUNCTION
pagila=# SELECT iheartphp('Robert');
    iheartphp
-------------------
 Robert loves PHP!
(1 row)

How useful!
pl/php basics
CREATE OR REPLACE FUNCTION iheartphp(text)
RETURNS text
LANGUAGE plphpu
STRICT
AS $$
       $retval = $args[0] . ' loves PHP!';
       return $retval;
$$;
CREATE FUNCTION
pagila=# SELECT iheartphp('Robert');
    iheartphp
-------------------
 Robert loves PHP!
(1 row)

How useful!
pl/php not so basics
    Need a page to show us inventory
●




    An item is in stock if we have no rows in our
●


    rental table, or all rows have a return date
    Normally this would be two queries
●




    Making it a function will consolidate logic and
●


    save round trips
CREATE OR REPLACE FUNCTION movie_in_stock(integer)
RETURNS Boolean
LANGUAGE plphpu
AS $$
  $sql = quot;SELECT count(*) FROM rental WHERE inventory_id = quot;.$args[0];
  $res = spi_exec($sql);
  $row = spi_fetch_row($res);
  if ($row['count'] == 0)
      return 1;
  $sql = quot;SELECT count(rental_id) FROM inventory LEFT JOIN rental USING (inventory_id)
          WHERE inventory.inventory_id = quot;.$args[0].quot; AND rental.return_date IS NULLquot;;

  $res = spi_exec($sql);
  $row = spi_fetch_row($res);
  if ($row['count'] > 0)
  {
      return 0 ;
  }
  else
  {
      return 1;
  };
$$;
CREATE OR REPLACE FUNCTION movie_in_stock(integer)
RETURNS Boolean
LANGUAGE plphpu
AS $$
  $sql = quot;SELECT count(*) FROM rental WHERE inventory_id = quot;.$args[0];
  $res = spi_exec($sql);
  $row = spi_fetch_row($res);
  if ($row['count'] == 0)
      return 1;
  $sql = quot;SELECT count(rental_id) FROM inventory LEFT JOIN rental USING (inventory_id)
          WHERE inventory.inventory_id = quot;.$args[0].quot; AND rental.return_date IS NULLquot;;

  $res = spi_exec($sql);
  $row = spi_fetch_row($res);
  if ($row['count'] > 0)
  {
      return 0 ;
  }
  else
  {
      return 1;
  };
$$;
spi functions?
    Internal functions for interacting with the db
●



        spi_exec :: execute a query with optional limit.
    –

        spi_status :: return status of a previous query.
    –

        spi_fetch_row :: return associative array of the
    –
        row's results.
        spi_processed :: return the number of tuples in a
    –
        result.
        spi_rewind :: put the row cursor at the beginning
    –
        of the result.
CREATE OR REPLACE FUNCTION movie_in_stock(integer)
RETURNS Boolean
LANGUAGE plphpu
AS $$
  $sql = quot;SELECT count(*) FROM rental WHERE inventory_id = quot;.$args[0];
  $res = spi_exec($sql);
  $row = spi_fetch_row($res);
  if ($row['count'] == 0)
      return 1;
  $sql = quot;SELECT count(rental_id) FROM inventory LEFT JOIN rental USING (inventory_id)
          WHERE inventory.inventory_id = quot;.$args[0].quot; AND rental.return_date IS NULLquot;;

  $res = spi_exec($sql);
  $row = spi_fetch_row($res);
  if ($row['count'] > 0)
  {
      return 0 ;
  }
  else
  {
      return 1;
  };
$$;
CREATE OR REPLACE FUNCTION movie_in_stock(integer)
RETURNS Boolean
LANGUAGE plphpu
AS $$
  $sql = quot;SELECT count(*) FROM rental WHERE inventory_id = quot;.$args[0];
  $res = spi_exec($sql);
  $row = spi_fetch_row($res);
  if ($row['count'] == 0)
      return 1;
  $sql = quot;SELECT count(rental_id) FROM inventory LEFT JOIN rental USING (inventory_id)
          WHERE inventory.inventory_id = quot;.$args[0].quot; AND rental.return_date IS NULLquot;;

  $res = spi_exec($sql);
  $row = spi_fetch_row($res);
  if ($row['count'] > 0)
  {
      return 0 ;
  }
  else
  {
      return 1;
  };
$$;
CREATE OR REPLACE FUNCTION movie_in_stock(integer)
RETURNS Boolean
LANGUAGE plphpu
AS $$
  $sql = quot;SELECT count(*) FROM rental WHERE inventory_id = quot;.$args[0];
  $res = spi_exec($sql);
  $row = spi_fetch_row($res);
  if ($row['count'] == 0)
      return 1;
  $sql = quot;SELECT count(rental_id) FROM inventory LEFT JOIN rental USING (inventory_id)
          WHERE inventory.inventory_id = quot;.$args[0].quot; AND rental.return_date IS NULLquot;;

  $res = spi_exec($sql);
  $row = spi_fetch_row($res);
  if ($row['count'] > 0)
  {
      return 0 ;
  }
  else
  {
      return 1;
  };
$$;
PHP Functions
         Most PHP functions can be used inside
     ●


         pl/php functions
CREATE OR REPLACE FUNCTION simplefunc(text,text)
RETURNS text
LANGUAGE plphpu
AS $$
  return 'Did you know '. ucwords(strrev($args[0])) .' is '. strtolower($args[1]) .' backwards?';
$$;

                     pagila=# select simplefunc('inside out','outside in');
                                       simplefunc
                     ------------------------------------------------------
                      Did you know Tuo Edisni is outside in backwards?
                     (1 row)
PHP Functions
CREATE OR REPLACE FUNCTION notsimplefunc()
RETURNS text
LANGUAGE plphpu
AS $$
  $sql = quot;select version()quot;;
  $c = pg_connect(quot;host=10.225.105.53 dbname=template1 user=postgresquot;);
  $r = pg_query($c,$sql);
  $v = pg_fetch_result($r,0,0);
  return $v;
$$;
PHP Functions
pagila=# SELECT notsimplefunc();
                                       nosimplefunc
-----------------------------------------------------------------------------------------------------------
 PostgreSQL 8.1.1 on i686-redhat-linux-gnu, compiled by GCC gcc (GCC) 3.4.2 20041017
(Red Hat 3.4.2-6.fc3)
(1 row)

pagila=# SELECT version();
                                        version
-------------------------------------------------------------------------------------------------------
 PostgreSQL 8.1.1 on i686-redhat-linux-gnu, compiled by GCC gcc (GCC) 4.0.1 20050727
(Red Hat 4.0.1-5)
(1 row)

     Connect to external database                         Does have scary implications
    ●                                                    ●



     Normally not recommended                             But this kind of flexibility can be cool
    ●                                                    ●
PHP Functions
CREATE OR REPLACE FUNCTION wickedfunc()
RETURNS text
LANGUAGE plphpu
as $$
  $c = mysql_connect(quot;10.225.105.94quot;,quot;sakilaquot;);
  $v = mysql_get_server_info();

  return $v;
$$;
PHP Functions
CREATE OR REPLACE FUNCTION wickedfunc()
RETURNS text
LANGUAGE plphpu
as $$
  $c = mysql_connect(quot;10.225.105.94quot;,quot;sakilaquot;);
  $v = mysql_get_server_info();

  return $v;
$$;


          pagila=# SELECT wickedfunc();
           wickedfunc
          --------------
           5.1.9-beta
          (1 row)
the PEAR example
    Can use PEAR modules inside functions
●




    Walk through example for validating email
●




    Pagila database
●


    (http://pgfoundry.org/projects/dbsamples/)
    Validate package
●


    (http://pear.php.net/package/Validate)
the Pear example

CREATE OR REPLACE FUNCTION valid_email(text)
RETURNS boolean
IMMUTABLE
LANGUAGE plphpu
AS $$
  require_once 'Validate.php';

 $validate = new Validate();

  return $validate->email(quot;$args[0]quot;,array(“check_domain”=>false,”use_rfc822”=>true)) ? 1 : 0;
$$;
the Pear example
pagila=# SELECT valid_email('xzilla@users.sourceforge.net');
valid_email
--------------------

t
(1 row)
pagila=# SELECT valid_email ('Robert Treat <xzilla@ users . sf . net>');
valid_email
---------------------

t
(1 row)
pagila=# SELECT valid_email('www.brighterlamp.org');
valid_email
---------------------

f
(1 row)
the Pear example
    Functions may inter-operate with any other
●


    part of the database system


             CREATE DOMAIN validemail AS text
             NOT NULL
             CHECK ( valid_email(VALUE) );
the Pear example
    Functions may inter-operate with any other
●


    part of the database system


             CREATE DOMAIN validemail AS text
             NOT NULL
             CHECK ( valid_email(VALUE) );
the Pear example
    Functions may inter-operate with any other
●


    part of the database system


             CREATE DOMAIN validemail AS text
             NOT NULL
             CHECK ( valid_email(VALUE) );
the Pear example
     pagila=# ALTER TABLE customer ALTER email TYPE validemail ;
     ALTER TABLE



    All data must pass through our function
●




    Validates all data in table
●




    Validates all data inserts and updates
●
the Pear example
pagila=# INSERT INTO customer (store_id, first_name, last_name, email, address_id, active)
pagila-# VALUES (2,'pete','hache-pee','l33t@aol',40,1);
ERROR: value for domain validemail violates check constraint quot;validemail_checkquot;




        No special syntax needed
    ●




        Error messages reference function
    ●




        We can tweak rules by modifying the function
    ●
pl/php triggers
    pl/php functions can be used as triggers too
●




    Can access new and old data in the table
●




    PostgreSQL gives us access to special trigger
●


    specific information
pl/php triggers
    pl/php functions can be used as triggers too
●




    Can access new and old data in the table
●




    PostgreSQL gives us access to special trigger
●


    specific information
    Example: Log overdue rental returns for
●


    customers automatically through functions
pl/php triggers
pagila=# d customer
                                   Table quot;public.customerquot;
   Column |               Type             |                      Modifiers
-------------+-----------------------------+----------------------------------------------------------------
 customer_id | integer                        | not null default nextval('customer_customer_id_seq'::regclass)
 store_id | smallint                          | not null
 first_name | character varying(45)                | not null
 last_name | character varying(45)                 | not null
 email       | character varying(50)               |
 address_id | smallint                       | not null
 activebool | boolean                        | not null default true
 create_date | date                          | not null default ('now'::text)::date
 last_update | timestamp without time zone | default now()
 active      | integer                   |
Indexes:
 quot;customer_pkeyquot; PRIMARY KEY, btree (customer_id)
 quot;idx_fk_address_idquot; btree (address_id)
 quot;idx_fk_store_idquot; btree (store_id)
 quot;idx_last_namequot; btree (last_name)
Foreign-key constraints:
  quot;customer_address_id_fkeyquot; FOREIGN KEY (address_id) REFERENCES address(address_id) ON UPDATE CASCADE ON DELETE RESTRICT
  quot;customer_store_id_fkeyquot; FOREIGN KEY (store_id) REFERENCES store(store_id) ON UPDATE CASCADE ON DELETE RESTRICT
Triggers:
   last_updated BEFORE UPDATE ON customer FOR EACH ROW EXECUTE PROCEDURE last_updated()
pl/php triggers
pagila=# d rental
                                   Table quot;public.rentalquot;
   Column |                Type              |                    Modifiers
--------------+-----------------------------+------------------------------------------------------------
 rental_id | integer                       | not null default nextval('rental_rental_id_seq'::regclass)
 rental_date | timestamp without time zone | not null
 inventory_id | integer                       | not null
 customer_id | smallint                         | not null
 return_date | timestamp without time zone |
 staff_id | smallint                      | not null
 last_update | timestamp without time zone | not null default now()
Indexes:
  quot;rental_pkeyquot; PRIMARY KEY, btree (rental_id)
 quot;idx_unq_rental_rental_date_inventory_id_customer_idquot; UNIQUE, btree (rental_date, inventory_id, customer_id)
 quot;idx_fk_inventory_idquot; btree (inventory_id)
Foreign-key constraints:
 quot;rental_customer_id_fkeyquot; FOREIGN KEY (customer_id) REFERENCES customer(customer_id) ON UPDATE CASCADE ON DELETE RESTRICT
 quot;rental_inventory_id_fkeyquot; FOREIGN KEY (inventory_id) REFERENCES inventory(inventory_id) ON UPDATE CASCADE ON DELETE RESTRICT
 quot;rental_staff_id_fkeyquot; FOREIGN KEY (staff_id) REFERENCES staff(staff_id) ON UPDATE CASCADE ON DELETE RESTRICT
Triggers:
   last_updated BEFORE UPDATE ON rental FOR EACH ROW EXECUTE PROCEDURE last_updated()
pl/php triggers
               CREATE TABLE overdue_log
               (
                  overdue_log_id serial,
                  customer_id integer,
                  days_overdue integer
               );


    Each record gets a logical primary key
●



    Store the customer id and the number of days
●


    rental was overdue
pl/php triggers
                CREATE TABLE overdue_log
                (
                   overdue_log_id serial,
                   customer_id integer,
                   days_overdue integer
                );


    Each record gets a logical primary key
●



    Store the customer id and the number of days
●


    rental was overdue
    Yes, this table is fake... no FK's, no
●


    timestamps, etc...
pl/php triggers – special variables
    $_TD[“old”] - Old data being removed from
●


    table
    $_TD[“new”] - New data being written to table
●



    Associative arrays, indexed by field names
●



    Null values not included
●



    Other special variables
●



        trigger name, trigger action, table name, etc...
    –
pl/php trigger function
CREATE OR REPLACE FUNCTION watch_overdue()
RETURNS trigger
LANGUAGE plphpu
AS $$
  $new =& $_TD['new'];

   $sql = quot;SELECT
           rental_date + (rental_duration * '1 day'::interval) as due_date
        FROM
           rental
           INNER JOIN inventory USING (inventory_id)
           INNER JOIN film USING (film_id)
        WHERE
           rental_id =quot;. $new['rental_id'];

   $rs = spi_exec($sql);
   $r = spi_fetch_row($rs);

continued...
pl/php trigger function
CREATE OR REPLACE FUNCTION watch_overdue()
RETURNS trigger
LANGUAGE plphpu
AS $$
  $new =& $_TD['new'];

   $sql = quot;SELECT
           rental_date + (rental_duration * '1 day'::interval) as due_date
        FROM
           rental
           INNER JOIN inventory USING (inventory_id)
           INNER JOIN film USING (film_id)
        WHERE
           rental_id =quot;. $new['rental_id'];

   $rs = spi_exec($sql);
   $r = spi_fetch_row($rs);

continued...
pl/php trigger function
continued...

pg_raise('notice',$r['due_date']);
pg_raise('notice',$new['return_date']);
  if ($new['return_date'] > $r['due_date'])
  {
      /* rental is overdue, we need to convert our dates to php time values,
         find the difference between them, and then convert that to days */

        $dayo = (strtotime($new['return_date']) - strtotime($r['due_date']))/60/60/24;
        pg_raise('notice',$dayo);

        $sql = quot;INSERT INTO overdue_log (customer_id,days_overdue)
                VALUES (quot;.$new['customer_id'].quot;,quot;.$dayo.quot;)quot;;

        $rs = spi_exec($sql);
   };

  return null;
$$;
pl/php trigger function
continued...

pg_raise('notice',$r['due_date']);
pg_raise('notice',$new['return_date']);
  if ($new['return_date'] > $r['due_date'])
  {
      /* rental is overdue, we need to convert our dates to php time values,
         find the difference between them, and then convert that to days */

        $dayo = (strtotime($new['return_date']) - strtotime($r['due_date']))/60/60/24;
        pg_raise('notice',$dayo);

        $sql = quot;INSERT INTO overdue_log (customer_id,days_overdue)
                VALUES (quot;.$new['customer_id'].quot;,quot;.$dayo.quot;)quot;;

        $rs = spi_exec($sql);
   };

  return null;
$$;
pl/php trigger function
continued...

pg_raise('notice',$r['due_date']);
pg_raise('notice',$new['return_date']);
  if ($new['return_date'] > $r['due_date'])
  {
      /* rental is overdue, we need to convert our dates to php time values,
         find the difference between them, and then convert that to days */

        $dayo = (strtotime($new['return_date']) - strtotime($r['due_date']))/60/60/24;
        pg_raise('notice',$dayo);

        $sql = quot;INSERT INTO overdue_log (customer_id,days_overdue)
                VALUES (quot;.$new['customer_id'].quot;,quot;.$dayo.quot;)quot;;

        $rs = spi_exec($sql);
   };

  return null;
$$;
pl/php trigger function
continued...

pg_raise('notice',$r['due_date']);
pg_raise('notice',$new['return_date']);
  if ($new['return_date'] > $r['due_date'])
  {
      /* rental is overdue, we need to convert our dates to php time values,
         find the difference between them, and then convert that to days */

        $dayo = (strtotime($new['return_date']) - strtotime($r['due_date']))/60/60/24;
        pg_raise('notice',$dayo);

        $sql = quot;INSERT INTO overdue_log (customer_id,days_overdue)
                VALUES (quot;.$new['customer_id'].quot;,quot;.$dayo.quot;)quot;;

        $rs = spi_exec($sql);
   };

  return null;
$$;
pl/php triggers (the trigger)
            CREATE TRIGGER watch_overdue
            AFTER insert or update
            ON rental
            FOR EACH row
            EXECUTE PROCEDURE watch_overdue();



    No special syntax needed
–

    Trigger fires on any insert or update
–

    We can tweak rules by modifying the function
–
pl/php triggers


pagila=# INSERT INTO rental
pagila-# VALUES (DEFAULT,now() - '1 month'::interval,2792,549,now(),1);
pl/php triggers


pagila=# INSERT INTO rental
pagila-# VALUES (DEFAULT,now() - '1 month'::interval,2792,549,now(),1);
NOTICE: plphp: 2006-07-30 11:27:56.854139
NOTICE: plphp: 2006-08-25 11:27:56.854139
NOTICE: plphp: 26
INSERT 0 1
pagila=#
pl/php triggers


pagila=# INSERT INTO rental
pagila-# VALUES (DEFAULT,now() - '1 month'::interval,2792,549,now(),1);
NOTICE: plphp: 2006-07-30 11:27:56.854139
NOTICE: plphp: 2006-08-25 11:27:56.854139
NOTICE: plphp: 26
INSERT 0 1
pagila=# SELECT * FROM overdue_log;
pl/php triggers


pagila=# INSERT INTO rental
pagila-# VALUES (DEFAULT,now() - '1 month'::interval,2792,549,now(),1);
NOTICE: plphp: 2006-07-30 11:27:56.854139
NOTICE: plphp: 2006-08-25 11:27:56.854139
NOTICE: plphp: 26
INSERT 0 1
pagila=# SELECT * FROM overdue_log;
 overdue_log_id | customer_id | days_overdue
----------------------+-----------------+----------------
                    1|            549 |          26
pl/php – one more example
CREATE OR REPLACE FUNCTION text_array_to_result(text[])
RETURNS setof text
LANGUAGE plphpu
AS $$

  // TRICKY!! $args[0] refers to the first argument of the function
  // so $args[0][0] refers to the first value of the array passed into the first argument!

  $i=0;
  while ($args[0][$i])
  {
     $ret = $args[0][$i];
     return_next($ret);
     $i++;
  }

  #pg_raise('notice',$args[0]);
$$;
pl/php – one more example
CREATE OR REPLACE FUNCTION text_array_to_result(text[])
RETURNS setof text
LANGUAGE plphpu
AS $$

  // TRICKY!! $args[0] refers to the first argument of the function
  // so $args[0][0] refers to the first value of the array passed into the first argument!

  $i=0;
  while ($args[0][$i])
  {
     $ret = $args[0][$i];
     return_next($ret);
     $i++;
  }

  #pg_raise('notice',$args[0]);
$$;
pl/php – one more example
CREATE OR REPLACE FUNCTION text_array_to_result(text[])
RETURNS setof text
LANGUAGE plphpu
AS $$

  // TRICKY!! $args[0] refers to the first argument of the function
  // so $args[0][0] refers to the first value of the array passed into the first argument!

  $i=0;
  while ($args[0][$i])
  {
     $ret = $args[0][$i];
     return_next($ret);
     $i++;
  }

  #pg_raise('notice',$args[0]);
$$;
pl/php – one more example
      pagila=# SELECT * FROM text_array_to_result('{txt arg 1,txt arg 2}');
       text_array_to_result
      ----------------------
       txt arg 1
       txt arg 2
      (2 rows)



    Works with arrays
●




    Works for set returning functions
●
pl/php – one more example
      pagila=# SELECT * FROM text_array_to_result('{txt arg 1,txt arg 2}');
       text_array_to_result
      ----------------------
       txt arg 1
       txt arg 2
      (2 rows)



    Works with arrays
●




    Works for set returning functions
●




    Oh yeah... no special syntax :-)
●
but wait, there's more!
    Composite data types
●



    Working with array types
●



    Global shared variables
●



    Polymorphic Arguments
●



    Polymorphic Return Types
●



    Composite Types
●
pl/php - caveats
    Rough around the edges
●


        sometimes uncover segfaults
    –

        lots of warnings / notices from php
    –

        no in / out parameters (8.1)
    –
pl/php - caveats
    Rough around the edges
●


        sometimes uncover segfaults
    –

        lots of warnings / notices from php
    –

        no in / out parameters (8.1)
    –

    Can't call other pl/php functions directly
●
pl/php - caveats
    Rough around the edges
●


        sometimes uncover segfaults
    –

        lots of warnings / notices from php
    –

        no in / out parameters (8.1)
    –

    Can't call other pl/php functions directly
●



    Not fully tested against all PHP functions
●
pl/php - caveats
    Rough around the edges
●


        sometimes uncover segfaults
    –

        lots of warnings / notices from php
    –

        no in / out parameters (8.1)
    –

    Can't call other pl/php functions directly
●



    Not fully tested against all PHP functions
●



    Needs some C developers to contribute
●
Thanks!
      Command Prompt, Inc.
         Alvarro Herrera
          Alexey Klyukin
       Greg Sabino-Mullane
             OmniTI
The PHP & PostgreSQL Communities
               :-)

Mais conteúdo relacionado

Mais procurados

PHP 5.6 New and Deprecated Features
PHP 5.6  New and Deprecated FeaturesPHP 5.6  New and Deprecated Features
PHP 5.6 New and Deprecated FeaturesMark Niebergall
 
Dependency management with Composer
Dependency management with ComposerDependency management with Composer
Dependency management with ComposerJason Grimes
 
Composer - Package Management for PHP. Silver Bullet?
Composer - Package Management for PHP. Silver Bullet?Composer - Package Management for PHP. Silver Bullet?
Composer - Package Management for PHP. Silver Bullet?Kirill Chebunin
 
Asynchronous Systems with Fn Flow
Asynchronous Systems with Fn FlowAsynchronous Systems with Fn Flow
Asynchronous Systems with Fn FlowJosé Paumard
 
Vagrant move over, here is Docker
Vagrant move over, here is DockerVagrant move over, here is Docker
Vagrant move over, here is DockerNick Belhomme
 
Laravel 4 package development
Laravel 4 package developmentLaravel 4 package development
Laravel 4 package developmentTihomir Opačić
 
Caching and tuning fun for high scalability @ FrOSCon 2011
Caching and tuning fun for high scalability @ FrOSCon 2011Caching and tuning fun for high scalability @ FrOSCon 2011
Caching and tuning fun for high scalability @ FrOSCon 2011Wim Godden
 
Debugging PHP with Xdebug - PHPUK 2018
Debugging PHP with Xdebug - PHPUK 2018Debugging PHP with Xdebug - PHPUK 2018
Debugging PHP with Xdebug - PHPUK 2018Mark Niebergall
 
Groovy Update, what's new in Groovy 1.8 and beyond - Guillaume Laforge - Spri...
Groovy Update, what's new in Groovy 1.8 and beyond - Guillaume Laforge - Spri...Groovy Update, what's new in Groovy 1.8 and beyond - Guillaume Laforge - Spri...
Groovy Update, what's new in Groovy 1.8 and beyond - Guillaume Laforge - Spri...Guillaume Laforge
 
Automatic PHP 7 Compatibility Checking Using php7cc (and PHPCompatibility)
Automatic PHP 7 Compatibility Checking Using php7cc (and PHPCompatibility)Automatic PHP 7 Compatibility Checking Using php7cc (and PHPCompatibility)
Automatic PHP 7 Compatibility Checking Using php7cc (and PHPCompatibility)Mark Niebergall
 
The why and how of moving to php 5.4
The why and how of moving to php 5.4The why and how of moving to php 5.4
The why and how of moving to php 5.4Wim Godden
 
How to deploy node to production
How to deploy node to productionHow to deploy node to production
How to deploy node to productionSean Hess
 
WordPress Plugin Unit Tests (FR - WordCamp Paris 2015)
WordPress Plugin Unit Tests (FR - WordCamp Paris 2015)WordPress Plugin Unit Tests (FR - WordCamp Paris 2015)
WordPress Plugin Unit Tests (FR - WordCamp Paris 2015)Ozh
 
Construire son JDK en 10 étapes
Construire son JDK en 10 étapesConstruire son JDK en 10 étapes
Construire son JDK en 10 étapesJosé Paumard
 
Deploying and maintaining your software with RPM/APT
Deploying and maintaining your software with RPM/APTDeploying and maintaining your software with RPM/APT
Deploying and maintaining your software with RPM/APTJoshua Thijssen
 
aptly: Debian repository management tool
aptly: Debian repository management toolaptly: Debian repository management tool
aptly: Debian repository management toolAndrey Smirnov
 
Puppet control-repo 
to the next level
Puppet control-repo 
to the next levelPuppet control-repo 
to the next level
Puppet control-repo 
to the next levelAlessandro Franceschi
 

Mais procurados (20)

PHP 5.6 New and Deprecated Features
PHP 5.6  New and Deprecated FeaturesPHP 5.6  New and Deprecated Features
PHP 5.6 New and Deprecated Features
 
Dependency management with Composer
Dependency management with ComposerDependency management with Composer
Dependency management with Composer
 
Composer - Package Management for PHP. Silver Bullet?
Composer - Package Management for PHP. Silver Bullet?Composer - Package Management for PHP. Silver Bullet?
Composer - Package Management for PHP. Silver Bullet?
 
Go Replicator
Go ReplicatorGo Replicator
Go Replicator
 
Asynchronous Systems with Fn Flow
Asynchronous Systems with Fn FlowAsynchronous Systems with Fn Flow
Asynchronous Systems with Fn Flow
 
Vagrant move over, here is Docker
Vagrant move over, here is DockerVagrant move over, here is Docker
Vagrant move over, here is Docker
 
Containers for sysadmins
Containers for sysadminsContainers for sysadmins
Containers for sysadmins
 
Laravel 4 package development
Laravel 4 package developmentLaravel 4 package development
Laravel 4 package development
 
Caching and tuning fun for high scalability @ FrOSCon 2011
Caching and tuning fun for high scalability @ FrOSCon 2011Caching and tuning fun for high scalability @ FrOSCon 2011
Caching and tuning fun for high scalability @ FrOSCon 2011
 
Debugging PHP with Xdebug - PHPUK 2018
Debugging PHP with Xdebug - PHPUK 2018Debugging PHP with Xdebug - PHPUK 2018
Debugging PHP with Xdebug - PHPUK 2018
 
Groovy Update, what's new in Groovy 1.8 and beyond - Guillaume Laforge - Spri...
Groovy Update, what's new in Groovy 1.8 and beyond - Guillaume Laforge - Spri...Groovy Update, what's new in Groovy 1.8 and beyond - Guillaume Laforge - Spri...
Groovy Update, what's new in Groovy 1.8 and beyond - Guillaume Laforge - Spri...
 
Automatic PHP 7 Compatibility Checking Using php7cc (and PHPCompatibility)
Automatic PHP 7 Compatibility Checking Using php7cc (and PHPCompatibility)Automatic PHP 7 Compatibility Checking Using php7cc (and PHPCompatibility)
Automatic PHP 7 Compatibility Checking Using php7cc (and PHPCompatibility)
 
The why and how of moving to php 5.4
The why and how of moving to php 5.4The why and how of moving to php 5.4
The why and how of moving to php 5.4
 
How to deploy node to production
How to deploy node to productionHow to deploy node to production
How to deploy node to production
 
WordPress Plugin Unit Tests (FR - WordCamp Paris 2015)
WordPress Plugin Unit Tests (FR - WordCamp Paris 2015)WordPress Plugin Unit Tests (FR - WordCamp Paris 2015)
WordPress Plugin Unit Tests (FR - WordCamp Paris 2015)
 
Construire son JDK en 10 étapes
Construire son JDK en 10 étapesConstruire son JDK en 10 étapes
Construire son JDK en 10 étapes
 
Deploying and maintaining your software with RPM/APT
Deploying and maintaining your software with RPM/APTDeploying and maintaining your software with RPM/APT
Deploying and maintaining your software with RPM/APT
 
PHP selber bauen
PHP selber bauenPHP selber bauen
PHP selber bauen
 
aptly: Debian repository management tool
aptly: Debian repository management toolaptly: Debian repository management tool
aptly: Debian repository management tool
 
Puppet control-repo 
to the next level
Puppet control-repo 
to the next levelPuppet control-repo 
to the next level
Puppet control-repo 
to the next level
 

Destaque

Database Scalability Patterns
Database Scalability PatternsDatabase Scalability Patterns
Database Scalability PatternsRobert Treat
 
What Ops Can Learn From Design
What Ops Can Learn From DesignWhat Ops Can Learn From Design
What Ops Can Learn From DesignRobert Treat
 
Scaling With Postgres
Scaling With PostgresScaling With Postgres
Scaling With PostgresRobert Treat
 
A Guide To PostgreSQL 9.0
A Guide To PostgreSQL 9.0A Guide To PostgreSQL 9.0
A Guide To PostgreSQL 9.0Robert Treat
 
Less Alarming Alerts - SRECon 2016
Less Alarming Alerts - SRECon 2016 Less Alarming Alerts - SRECon 2016
Less Alarming Alerts - SRECon 2016 Robert Treat
 
Managing Databases In A DevOps Environment 2016
Managing Databases In A DevOps Environment 2016Managing Databases In A DevOps Environment 2016
Managing Databases In A DevOps Environment 2016Robert Treat
 
Advanced WAL File Management With OmniPITR
Advanced WAL File Management With OmniPITRAdvanced WAL File Management With OmniPITR
Advanced WAL File Management With OmniPITRRobert Treat
 
Think_your_Postgres_backups_and_recovery_are_safe_lets_talk.pptx
Think_your_Postgres_backups_and_recovery_are_safe_lets_talk.pptxThink_your_Postgres_backups_and_recovery_are_safe_lets_talk.pptx
Think_your_Postgres_backups_and_recovery_are_safe_lets_talk.pptxPayal Singh
 
Out of the box replication in postgres 9.4
Out of the box replication in postgres 9.4Out of the box replication in postgres 9.4
Out of the box replication in postgres 9.4Denish Patel
 
PostgreSQL 9.6 Performance-Scalability Improvements
PostgreSQL 9.6 Performance-Scalability ImprovementsPostgreSQL 9.6 Performance-Scalability Improvements
PostgreSQL 9.6 Performance-Scalability ImprovementsPGConf APAC
 

Destaque (11)

Database Scalability Patterns
Database Scalability PatternsDatabase Scalability Patterns
Database Scalability Patterns
 
What Ops Can Learn From Design
What Ops Can Learn From DesignWhat Ops Can Learn From Design
What Ops Can Learn From Design
 
Scaling With Postgres
Scaling With PostgresScaling With Postgres
Scaling With Postgres
 
A Guide To PostgreSQL 9.0
A Guide To PostgreSQL 9.0A Guide To PostgreSQL 9.0
A Guide To PostgreSQL 9.0
 
Less Alarming Alerts - SRECon 2016
Less Alarming Alerts - SRECon 2016 Less Alarming Alerts - SRECon 2016
Less Alarming Alerts - SRECon 2016
 
Managing Databases In A DevOps Environment 2016
Managing Databases In A DevOps Environment 2016Managing Databases In A DevOps Environment 2016
Managing Databases In A DevOps Environment 2016
 
Advanced WAL File Management With OmniPITR
Advanced WAL File Management With OmniPITRAdvanced WAL File Management With OmniPITR
Advanced WAL File Management With OmniPITR
 
Think_your_Postgres_backups_and_recovery_are_safe_lets_talk.pptx
Think_your_Postgres_backups_and_recovery_are_safe_lets_talk.pptxThink_your_Postgres_backups_and_recovery_are_safe_lets_talk.pptx
Think_your_Postgres_backups_and_recovery_are_safe_lets_talk.pptx
 
Out of the box replication in postgres 9.4
Out of the box replication in postgres 9.4Out of the box replication in postgres 9.4
Out of the box replication in postgres 9.4
 
PostgreSQL 9.6 Performance-Scalability Improvements
PostgreSQL 9.6 Performance-Scalability ImprovementsPostgreSQL 9.6 Performance-Scalability Improvements
PostgreSQL 9.6 Performance-Scalability Improvements
 
Backups
BackupsBackups
Backups
 

Semelhante a Intro to pl/PHP Oscon2007

Performance Profiling in Rust
Performance Profiling in RustPerformance Profiling in Rust
Performance Profiling in RustInfluxData
 
9 steps to install and configure postgre sql from source on linux
9 steps to install and configure postgre sql from source on linux9 steps to install and configure postgre sql from source on linux
9 steps to install and configure postgre sql from source on linuxchinkshady
 
Perl In The Command Line
Perl In The Command LinePerl In The Command Line
Perl In The Command LineMarcos Rebelo
 
Drupal and Open shift (and php)
Drupal and Open shift (and php)Drupal and Open shift (and php)
Drupal and Open shift (and php)Phase2
 
A General Purpose Docker Image for PHP
A General Purpose Docker Image for PHPA General Purpose Docker Image for PHP
A General Purpose Docker Image for PHPRobert Lemke
 
Prepare for PHP Test Fest 2009
Prepare for PHP Test Fest 2009Prepare for PHP Test Fest 2009
Prepare for PHP Test Fest 2009PHPBelgium
 
Bundling Packages and Deploying Applications with RPM
Bundling Packages and Deploying Applications with RPMBundling Packages and Deploying Applications with RPM
Bundling Packages and Deploying Applications with RPMAlexander Shopov
 
Linux Troubleshooting
Linux TroubleshootingLinux Troubleshooting
Linux TroubleshootingKeith Wright
 
PHP: The easiest language to learn.
PHP: The easiest language to learn.PHP: The easiest language to learn.
PHP: The easiest language to learn.Binny V A
 
mapserver_install_linux
mapserver_install_linuxmapserver_install_linux
mapserver_install_linuxtutorialsruby
 
mapserver_install_linux
mapserver_install_linuxmapserver_install_linux
mapserver_install_linuxtutorialsruby
 
mapserver_install_linux
mapserver_install_linuxmapserver_install_linux
mapserver_install_linuxtutorialsruby
 
mapserver_install_linux
mapserver_install_linuxmapserver_install_linux
mapserver_install_linuxtutorialsruby
 
Award-winning technology: Oxid loves the query cache
Award-winning technology: Oxid loves the query cacheAward-winning technology: Oxid loves the query cache
Award-winning technology: Oxid loves the query cacheUlf Wendel
 
Running PHP on a Java container
Running PHP on a Java containerRunning PHP on a Java container
Running PHP on a Java containernetinhoteixeira
 
PM : code faster
PM : code fasterPM : code faster
PM : code fasterPHPPRO
 
autopkgtest lightning talk
autopkgtest lightning talkautopkgtest lightning talk
autopkgtest lightning talkmartin-pitt
 
2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps
2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps
2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOpsОмские ИТ-субботники
 
RPM: Speed up your deploy
RPM: Speed up your deployRPM: Speed up your deploy
RPM: Speed up your deployfcrippa
 

Semelhante a Intro to pl/PHP Oscon2007 (20)

Performance Profiling in Rust
Performance Profiling in RustPerformance Profiling in Rust
Performance Profiling in Rust
 
9 steps to install and configure postgre sql from source on linux
9 steps to install and configure postgre sql from source on linux9 steps to install and configure postgre sql from source on linux
9 steps to install and configure postgre sql from source on linux
 
Perl In The Command Line
Perl In The Command LinePerl In The Command Line
Perl In The Command Line
 
Lumen
LumenLumen
Lumen
 
Drupal and Open shift (and php)
Drupal and Open shift (and php)Drupal and Open shift (and php)
Drupal and Open shift (and php)
 
A General Purpose Docker Image for PHP
A General Purpose Docker Image for PHPA General Purpose Docker Image for PHP
A General Purpose Docker Image for PHP
 
Prepare for PHP Test Fest 2009
Prepare for PHP Test Fest 2009Prepare for PHP Test Fest 2009
Prepare for PHP Test Fest 2009
 
Bundling Packages and Deploying Applications with RPM
Bundling Packages and Deploying Applications with RPMBundling Packages and Deploying Applications with RPM
Bundling Packages and Deploying Applications with RPM
 
Linux Troubleshooting
Linux TroubleshootingLinux Troubleshooting
Linux Troubleshooting
 
PHP: The easiest language to learn.
PHP: The easiest language to learn.PHP: The easiest language to learn.
PHP: The easiest language to learn.
 
mapserver_install_linux
mapserver_install_linuxmapserver_install_linux
mapserver_install_linux
 
mapserver_install_linux
mapserver_install_linuxmapserver_install_linux
mapserver_install_linux
 
mapserver_install_linux
mapserver_install_linuxmapserver_install_linux
mapserver_install_linux
 
mapserver_install_linux
mapserver_install_linuxmapserver_install_linux
mapserver_install_linux
 
Award-winning technology: Oxid loves the query cache
Award-winning technology: Oxid loves the query cacheAward-winning technology: Oxid loves the query cache
Award-winning technology: Oxid loves the query cache
 
Running PHP on a Java container
Running PHP on a Java containerRunning PHP on a Java container
Running PHP on a Java container
 
PM : code faster
PM : code fasterPM : code faster
PM : code faster
 
autopkgtest lightning talk
autopkgtest lightning talkautopkgtest lightning talk
autopkgtest lightning talk
 
2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps
2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps
2017-03-11 02 Денис Нелюбин. Docker & Ansible - лучшие друзья DevOps
 
RPM: Speed up your deploy
RPM: Speed up your deployRPM: Speed up your deploy
RPM: Speed up your deploy
 

Mais de Robert Treat

Advanced Int->Bigint Conversions
Advanced Int->Bigint ConversionsAdvanced Int->Bigint Conversions
Advanced Int->Bigint ConversionsRobert Treat
 
Explaining Explain
Explaining ExplainExplaining Explain
Explaining ExplainRobert Treat
 
the-lost-art-of-plpgsql
the-lost-art-of-plpgsqlthe-lost-art-of-plpgsql
the-lost-art-of-plpgsqlRobert Treat
 
Managing Chaos In Production: Testing vs Monitoring
Managing Chaos In Production: Testing vs MonitoringManaging Chaos In Production: Testing vs Monitoring
Managing Chaos In Production: Testing vs MonitoringRobert Treat
 
Postgres 9.4 First Look
Postgres 9.4 First LookPostgres 9.4 First Look
Postgres 9.4 First LookRobert Treat
 
Less Alarming Alerts!
Less Alarming Alerts!Less Alarming Alerts!
Less Alarming Alerts!Robert Treat
 
Past, Present, and Pachyderm - All Things Open - 2013
Past, Present, and Pachyderm - All Things Open - 2013Past, Present, and Pachyderm - All Things Open - 2013
Past, Present, and Pachyderm - All Things Open - 2013Robert Treat
 
Big Bad "Upgraded" Postgres
Big Bad "Upgraded" PostgresBig Bad "Upgraded" Postgres
Big Bad "Upgraded" PostgresRobert Treat
 
Managing Databases In A DevOps Environment
Managing Databases In A DevOps EnvironmentManaging Databases In A DevOps Environment
Managing Databases In A DevOps EnvironmentRobert Treat
 
The Essential PostgreSQL.conf
The Essential PostgreSQL.confThe Essential PostgreSQL.conf
The Essential PostgreSQL.confRobert Treat
 
Scaling with Postgres (Highload++ 2010)
Scaling with Postgres (Highload++ 2010)Scaling with Postgres (Highload++ 2010)
Scaling with Postgres (Highload++ 2010)Robert Treat
 
Intro to Postgres 9 Tutorial
Intro to Postgres 9 TutorialIntro to Postgres 9 Tutorial
Intro to Postgres 9 TutorialRobert Treat
 
Intro to Postgres 8.4 Tutorial
Intro to Postgres 8.4 TutorialIntro to Postgres 8.4 Tutorial
Intro to Postgres 8.4 TutorialRobert Treat
 
The Essential postgresql.conf
The Essential postgresql.confThe Essential postgresql.conf
The Essential postgresql.confRobert Treat
 
PostgreSQL Partitioning, PGCon 2007
PostgreSQL Partitioning, PGCon 2007PostgreSQL Partitioning, PGCon 2007
PostgreSQL Partitioning, PGCon 2007Robert Treat
 
Pro PostgreSQL, OSCon 2008
Pro PostgreSQL, OSCon 2008Pro PostgreSQL, OSCon 2008
Pro PostgreSQL, OSCon 2008Robert Treat
 
Database Anti Patterns
Database Anti PatternsDatabase Anti Patterns
Database Anti PatternsRobert Treat
 

Mais de Robert Treat (20)

Advanced Int->Bigint Conversions
Advanced Int->Bigint ConversionsAdvanced Int->Bigint Conversions
Advanced Int->Bigint Conversions
 
Explaining Explain
Explaining ExplainExplaining Explain
Explaining Explain
 
the-lost-art-of-plpgsql
the-lost-art-of-plpgsqlthe-lost-art-of-plpgsql
the-lost-art-of-plpgsql
 
Managing Chaos In Production: Testing vs Monitoring
Managing Chaos In Production: Testing vs MonitoringManaging Chaos In Production: Testing vs Monitoring
Managing Chaos In Production: Testing vs Monitoring
 
Postgres 9.4 First Look
Postgres 9.4 First LookPostgres 9.4 First Look
Postgres 9.4 First Look
 
Less Alarming Alerts!
Less Alarming Alerts!Less Alarming Alerts!
Less Alarming Alerts!
 
Past, Present, and Pachyderm - All Things Open - 2013
Past, Present, and Pachyderm - All Things Open - 2013Past, Present, and Pachyderm - All Things Open - 2013
Past, Present, and Pachyderm - All Things Open - 2013
 
Big Bad "Upgraded" Postgres
Big Bad "Upgraded" PostgresBig Bad "Upgraded" Postgres
Big Bad "Upgraded" Postgres
 
Managing Databases In A DevOps Environment
Managing Databases In A DevOps EnvironmentManaging Databases In A DevOps Environment
Managing Databases In A DevOps Environment
 
The Essential PostgreSQL.conf
The Essential PostgreSQL.confThe Essential PostgreSQL.conf
The Essential PostgreSQL.conf
 
Pro Postgres 9
Pro Postgres 9Pro Postgres 9
Pro Postgres 9
 
Scaling with Postgres (Highload++ 2010)
Scaling with Postgres (Highload++ 2010)Scaling with Postgres (Highload++ 2010)
Scaling with Postgres (Highload++ 2010)
 
Intro to Postgres 9 Tutorial
Intro to Postgres 9 TutorialIntro to Postgres 9 Tutorial
Intro to Postgres 9 Tutorial
 
Check Please!
Check Please!Check Please!
Check Please!
 
Intro to Postgres 8.4 Tutorial
Intro to Postgres 8.4 TutorialIntro to Postgres 8.4 Tutorial
Intro to Postgres 8.4 Tutorial
 
The Essential postgresql.conf
The Essential postgresql.confThe Essential postgresql.conf
The Essential postgresql.conf
 
PostgreSQL Partitioning, PGCon 2007
PostgreSQL Partitioning, PGCon 2007PostgreSQL Partitioning, PGCon 2007
PostgreSQL Partitioning, PGCon 2007
 
Pro PostgreSQL, OSCon 2008
Pro PostgreSQL, OSCon 2008Pro PostgreSQL, OSCon 2008
Pro PostgreSQL, OSCon 2008
 
Database Anti Patterns
Database Anti PatternsDatabase Anti Patterns
Database Anti Patterns
 
Pro PostgreSQL
Pro PostgreSQLPro PostgreSQL
Pro PostgreSQL
 

Último

A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024Results
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processorsdebabhi2
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking MenDelhi Call girls
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfEnterprise Knowledge
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Drew Madelung
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptxHampshireHUG
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024Rafal Los
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsMaria Levchenko
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Enterprise Knowledge
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...Martijn de Jong
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreternaman860154
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilV3cube
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024The Digital Insurer
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationRadu Cotescu
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking MenDelhi Call girls
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationSafe Software
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024The Digital Insurer
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...apidays
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesSinan KOZAK
 

Último (20)

A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024A Call to Action for Generative AI in 2024
A Call to Action for Generative AI in 2024
 
Exploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone ProcessorsExploring the Future Potential of AI-Enabled Smartphone Processors
Exploring the Future Potential of AI-Enabled Smartphone Processors
 
08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men08448380779 Call Girls In Civil Lines Women Seeking Men
08448380779 Call Girls In Civil Lines Women Seeking Men
 
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdfThe Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
The Role of Taxonomy and Ontology in Semantic Layers - Heather Hedden.pdf
 
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law DevelopmentsTrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
TrustArc Webinar - Stay Ahead of US State Data Privacy Law Developments
 
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
Strategies for Unlocking Knowledge Management in Microsoft 365 in the Copilot...
 
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
04-2024-HHUG-Sales-and-Marketing-Alignment.pptx
 
The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024The 7 Things I Know About Cyber Security After 25 Years | April 2024
The 7 Things I Know About Cyber Security After 25 Years | April 2024
 
Handwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed textsHandwritten Text Recognition for manuscripts and early printed texts
Handwritten Text Recognition for manuscripts and early printed texts
 
Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...Driving Behavioral Change for Information Management through Data-Driven Gree...
Driving Behavioral Change for Information Management through Data-Driven Gree...
 
2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...2024: Domino Containers - The Next Step. News from the Domino Container commu...
2024: Domino Containers - The Next Step. News from the Domino Container commu...
 
Presentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreterPresentation on how to chat with PDF using ChatGPT code interpreter
Presentation on how to chat with PDF using ChatGPT code interpreter
 
Developing An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of BrazilDeveloping An App To Navigate The Roads of Brazil
Developing An App To Navigate The Roads of Brazil
 
Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024Finology Group – Insurtech Innovation Award 2024
Finology Group – Insurtech Innovation Award 2024
 
Scaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organizationScaling API-first – The story of a global engineering organization
Scaling API-first – The story of a global engineering organization
 
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men08448380779 Call Girls In Greater Kailash - I Women Seeking Men
08448380779 Call Girls In Greater Kailash - I Women Seeking Men
 
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time AutomationFrom Event to Action: Accelerate Your Decision Making with Real-Time Automation
From Event to Action: Accelerate Your Decision Making with Real-Time Automation
 
Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024Tata AIG General Insurance Company - Insurer Innovation Award 2024
Tata AIG General Insurance Company - Insurer Innovation Award 2024
 
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
Apidays Singapore 2024 - Building Digital Trust in a Digital Economy by Veron...
 
Unblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen FramesUnblocking The Main Thread Solving ANRs and Frozen Frames
Unblocking The Main Thread Solving ANRs and Frozen Frames
 

Intro to pl/PHP Oscon2007

  • 1. An Introduction to pl/php by Robert Treat http://www.brighterlamp.org/
  • 2. What is pl/php aka PL/PHP, Pl/PHP, pl/PHP ● Database procedural language based on ● PHP Allows you to program inside the database ● using PHP
  • 3. Let's see an example eh? CREATE OR REPLACE FUNCTION hello_world() RETURNS text LANGUAGE plphp AS $$ $var = quot;howdy yallquot;; RETURN $var; $$;
  • 4. Let's see an example eh? CREATE OR REPLACE FUNCTION hello_world() RETURNS text LANGUAGE plphp AS $$ $var = quot;howdy yallquot;; RETURN $var; $$; pagila=# select hello_world(); hello_world ---------------- howdy yall (1 row)
  • 5. Let's see an example eh? CREATE OR REPLACE FUNCTION hello_world() RETURNS text LANGUAGE plphp AS $$ $var = quot;howdy yallquot;; RETURN $var; $$; pagila=# select hello_world(); hello_world ---------------- howdy yall (1 row) Fancy huh?
  • 6. Where does pl/php come from? Originally developed by Command Prompt, Inc. ● Currently maintained by Alvaro Herrera, Alexey ● Klyukin (both work for Command Prompt) Has gone through a number of re-writes ● http://plphp.commandprompt.com/ ●
  • 7. Who uses pl/php? We don't know... but it seems popular... ●
  • 10. So why do people use pl/php? Nicely integrates with PostgreSQL ● close to data – easily access tables and whatnot –
  • 11. So why do people use pl/php? Nicely integrates with PostgreSQL ● close to data – easily access tables and whatnot – Save on network traffic ●
  • 12. So why do people use pl/php? Nicely integrates with PostgreSQL ● close to data – easily access tables and whatnot – Save on network traffic ● You can use PHP to write it! ●
  • 13. Any reason to avoid it? PostgreSQL specific ●
  • 14. Any reason to avoid it? PostgreSQL specific (well, maybe that's really ● a reason to use it)
  • 15. Any reason to avoid it? PostgreSQL specific (well, maybe that's really ● a reason to use it) Adds dependencies to your database ● Code is still green ● Small user community ●
  • 16. Installation Pre-requisites: ● PostgreSQL 8.1+ –
  • 17. Installation Pre-requisites: ● PostgreSQL 8.1+ – -bash-3.00$ pg_config --version
  • 18. Installation Pre-requisites: ● PostgreSQL 8.1+ – -bash-3.00$ pg_config --version PostgreSQL 8.1.9
  • 19. Installation Pre-requisites: ● PostgreSQL 8.1+ – -bash-3.00$ pg_config --version PostgreSQL 8.1.9 Also need php development package (yum install – php-devel)
  • 20. Installation Pre-requisites: ● PostgreSQL 8.1+ – -bash-3.00$ pg_config --version PostgreSQL 8.1.9 Also need php development package (yum install – php-devel) [root@localhost html]# php-config --version
  • 21. Installation Pre-requisites: ● PostgreSQL 8.1+ – -bash-3.00$ pg_config --version PostgreSQL 8.1.9 Also need php development package (yum install – php-devel) [root@localhost html]# php-config --version 5.1.2
  • 22. Installation Grab the latest release tarball, unpack it, configure ● and make (simple eh?)
  • 23. Installation Grab the latest release tarball, unpack it, configure ● and make (simple eh?) rob@ridley:~/devel/plphp$
  • 24. Installation Grab the latest release tarball, unpack it, configure ● and make (simple eh?) rob@ridley:~/devel/plphp$ tar zxvf plphp-1.3.3.tar.gz
  • 25. Installation Grab the latest release tarball, unpack it, configure ● and make (simple eh?) rob@ridley:~/devel/plphp$ tar zxvf plphp-1.3.3.tar.gz ./plphp-1.3.3/ ./plphp-1.3.3/sql/ <snip> ./plphp-1.3.3/plphp.c rob@ridley:~/devel/plphp$
  • 26. Installation Grab the latest release tarball, unpack it, configure ● and make (simple eh?) rob@ridley:~/devel/plphp$ tar zxvf plphp-1.3.3.tar.gz ./plphp-1.3.3/ ./plphp-1.3.3/sql/ <snip> ./plphp-1.3.3/plphp.c rob@ridley:~/devel/plphp$ cd plphp-1.3.3
  • 27. Installation Grab the latest release tarball, unpack it, configure ● and make (simple eh?) rob@ridley:~/devel/plphp$ tar zxvf plphp-1.3.3.tar.gz ./plphp-1.3.3/ ./plphp-1.3.3/sql/ <snip> ./plphp-1.3.3/plphp.c rob@ridley:~/devel/plphp$ cd plphp-1.3.3 rob@ridley:~/devel/plphp/plphp-1.3.3$
  • 28. Installation Grab the latest release tarball, unpack it, configure ● and make (simple eh?) rob@ridley:~/devel/plphp$ tar zxvf plphp-1.3.3.tar.gz ./plphp-1.3.3/ ./plphp-1.3.3/sql/ <snip> ./plphp-1.3.3/plphp.c rob@ridley:~/devel/plphp$ cd plphp-1.3.3 rob@ridley:~/devel/plphp/plphp-1.3.3$ ./configure
  • 29. Installation Grab the latest release tarball, unpack it, configure ● and make (simple eh?) rob@ridley:~/devel/plphp$ tar zxvf plphp-1.3.3.tar.gz ./plphp-1.3.3/ ./plphp-1.3.3/sql/ <snip> ./plphp-1.3.3/plphp.c rob@ridley:~/devel/plphp$ cd plphp-1.3.3 rob@ridley:~/devel/plphp/plphp-1.3.3$ ./configure checking for gcc... gcc <snip> checking for pg_config... /usr/bin/pg_config checking for existence of /usr/lib/postgresql/8.1/lib/pgxs/src/makefiles/pgxs.mk... yes checking for PostgreSQL version... 8.1.9 checking for php-config... /usr/bin/php-config checking for php_module_startup in -lphp5... no checking for php_module_startup in -lphp4... no configure: error: Cannot locate a proper php library
  • 30. Installation – libphp5 no longer supports building against mod_php ● most distributions don't ship static php library ● don't be fooled! ● rob@ridley:~$ locate libphp ● /usr/lib/libphp5.so /usr/lib/apache2/modules/libphp5.so rob@ridley:~$ ls ­al /usr/lib/libphp5.so lrwxrwxrwx 1 root root 35 2006­08­26 20:43  /usr/lib/libphp5.so ­> /usr/lib/apache2/modules/libphp5.so
  • 31. Installation – libphp5 no longer supports building against mod_php ● most distributions don't ship static php library ● need to build your own php libs ● make libphp5.la install ● configure –enable-embed –prefix=your_dir; ● make install
  • 32. Installation configure plphp ● ./configure –with-php=/home/rob/devel/plphp/embedphp/ rob@ridley:~/devel/plphp/plphp-1.3.3$ checking for gcc... gcc <snip> checking for pg_config... /usr/bin/pg_config checking for existence of /usr/lib/postgresql/8.1/lib/pgxs/src/makefiles/pgxs.mk... yes checking for PostgreSQL version... 8.1.9 checking for php-config... /home/rob/devel/plphp/embedphp//bin/php-config checking for php_module_startup in -lphp5... yes configure: creating ./config.status config.status: creating Makefile config.status: creating config.h
  • 33. Installation sudo make install ● rob@ridley:~/devel/plphp/plphp-1.3.3$ sudo make install <snip> /bin/sh /usr/lib/postgresql/8.1/lib/pgxs/src/makefiles/../../config/install-sh -c -m 755 libplphp.so.0.0 /usr/lib/postgresql/8.1/lib/plphp.so
  • 34. Installing pl/php into the Database Once .so is compiled, you need to install the ● language into your database.
  • 35. Installing pl/php into the Database Once .so is compiled, you need to install the ● language into your database. Should be easier than compiling ●
  • 36. Installing pl/php into the Database Once .so is compiled, you need to install the ● language into your database. Should be easier than compiling ● Probably won't be... ●
  • 37. Installing pl/php into the Database pagila=# INSERT INTO pg_pltemplate VALUES pagila-# ('plphpu', 'f', 'plphp_call_handler', 'plphp_validator', '$libdir/plphp', NULL); INSERT 0 1 Creates an entry into the shared catalogs ● Does not mean that pl/php is installed! ● But you can now install it into any database ● using the “Create Language” command
  • 38. Installing pl/php into the Database pagila=#
  • 39. Installing pl/php into the Database pagila=# create language plphp;
  • 40. Installing pl/php into the Database pagila=# create language plphpu; ERROR: could not load library quot;/usr/lib/postgresql/8.1/lib/plphp.soquot;: /usr/lib/libphp5.so: undefined symbol: ap_loaded_modules
  • 41. Installing pl/php into the Database pagila=# create language plphpu; ERROR: could not load library quot;/usr/lib/postgresql/8.1/lib/plphp.soquot;: /usr/lib/libphp5.so: undefined symbol: ap_loaded_modules See? Simple...
  • 42. Installing pl/php into the Database pagila=# create language plphp; ERROR: could not load library quot;/usr/lib/pgsql/plphp.soquot;: libphp5.so: cannot open shared object file: No such file or directory See? Simple... PostgreSQL can't find the php shared library ● We need to find libphp5.so and set ● PostgreSQL up to find it.
  • 43. Installing pl/php into the Database [root@localhost pgsql]# locate libphp5.so /usr/lib/httpd/modules/libphp5.so [root@localhost pgsql]# pg_config --libdir /usr/lib [root@localhost pgsql]# ln -sf /usr/lib/httpd/modules/libphp5.so /usr/lib/ [root@localhost pgsql]# createlang -U postgres plphp pagila CREATE LANGUAGE
  • 44. Installing pl/php into the Database [root@localhost pgsql]# psql -U postgres pagila Welcome to psql 8.1.1, the PostgreSQL interactive terminal. Type: copyright for distribution terms h for help with SQL commands ? for help with psql commands g or terminate with semicolon to execute query q to quit pagila=# create language plphpu; CREATE LANGUAGE pagila=#
  • 45. pl/php vs. pl/phpu ? PostgreSQL offers “trusted” and “untrusted” ● languages Untrusted means it can access the file system ● More flexible, more useful, likely a good ● choice when working with any complexity Opens small security hole; be aware. ●
  • 46. pl/php basics CREATE OR REPLACE FUNCTION iheartphp(text) RETURNS text LANGUAGE plphpu STRICT AS $$ $retval = $args[0] . ' loves PHP!'; return $retval; $$; CREATE FUNCTION pagila=# SELECT iheartphp('Robert'); iheartphp ------------------- Robert loves PHP! (1 row) How useful!
  • 47. pl/php basics CREATE OR REPLACE FUNCTION iheartphp(text) RETURNS text LANGUAGE plphpu STRICT AS $$ $retval = $args[0] . ' loves PHP!'; return $retval; $$; CREATE FUNCTION pagila=# SELECT iheartphp('Robert'); iheartphp ------------------- Robert loves PHP! (1 row) How useful!
  • 48. pl/php basics CREATE OR REPLACE FUNCTION iheartphp(text) RETURNS text LANGUAGE plphpu STRICT AS $$ $retval = $args[0] . ' loves PHP!'; return $retval; $$; CREATE FUNCTION pagila=# SELECT iheartphp('Robert'); iheartphp ------------------- Robert loves PHP! (1 row) How useful!
  • 49. pl/php basics CREATE OR REPLACE FUNCTION iheartphp(text) RETURNS text LANGUAGE plphpu STRICT AS $$ $retval = $args[0] . ' loves PHP!'; return $retval; $$; CREATE FUNCTION pagila=# SELECT iheartphp('Robert'); iheartphp ------------------- Robert loves PHP! (1 row) How useful!
  • 50. pl/php basics CREATE OR REPLACE FUNCTION iheartphp(text) RETURNS text LANGUAGE plphpu STRICT AS $$ $retval = $args[0] . ' loves PHP!'; return $retval; $$; CREATE FUNCTION pagila=# SELECT iheartphp('Robert'); iheartphp ------------------- Robert loves PHP! (1 row) How useful!
  • 51. pl/php basics CREATE OR REPLACE FUNCTION iheartphp(text) RETURNS text LANGUAGE plphpu STRICT AS $$ $retval = $args[0] . ' loves PHP!'; return $retval; $$; CREATE FUNCTION pagila=# SELECT iheartphp('Robert'); iheartphp ------------------- Robert loves PHP! (1 row) How useful!
  • 52. pl/php basics CREATE OR REPLACE FUNCTION iheartphp(text) RETURNS text LANGUAGE plphpu STRICT AS $$ $retval = $args[0] . ' loves PHP!'; return $retval; $$; CREATE FUNCTION pagila=# SELECT iheartphp('Robert'); iheartphp ------------------- Robert loves PHP! (1 row) How useful!
  • 53. pl/php basics CREATE OR REPLACE FUNCTION iheartphp(text) RETURNS text LANGUAGE plphpu STRICT AS $$ $retval = $args[0] . ' loves PHP!'; return $retval; $$; CREATE FUNCTION pagila=# SELECT iheartphp('Robert'); iheartphp ------------------- Robert loves PHP! (1 row) How useful!
  • 54. pl/php not so basics Need a page to show us inventory ● An item is in stock if we have no rows in our ● rental table, or all rows have a return date Normally this would be two queries ● Making it a function will consolidate logic and ● save round trips
  • 55. CREATE OR REPLACE FUNCTION movie_in_stock(integer) RETURNS Boolean LANGUAGE plphpu AS $$ $sql = quot;SELECT count(*) FROM rental WHERE inventory_id = quot;.$args[0]; $res = spi_exec($sql); $row = spi_fetch_row($res); if ($row['count'] == 0) return 1; $sql = quot;SELECT count(rental_id) FROM inventory LEFT JOIN rental USING (inventory_id) WHERE inventory.inventory_id = quot;.$args[0].quot; AND rental.return_date IS NULLquot;; $res = spi_exec($sql); $row = spi_fetch_row($res); if ($row['count'] > 0) { return 0 ; } else { return 1; }; $$;
  • 56. CREATE OR REPLACE FUNCTION movie_in_stock(integer) RETURNS Boolean LANGUAGE plphpu AS $$ $sql = quot;SELECT count(*) FROM rental WHERE inventory_id = quot;.$args[0]; $res = spi_exec($sql); $row = spi_fetch_row($res); if ($row['count'] == 0) return 1; $sql = quot;SELECT count(rental_id) FROM inventory LEFT JOIN rental USING (inventory_id) WHERE inventory.inventory_id = quot;.$args[0].quot; AND rental.return_date IS NULLquot;; $res = spi_exec($sql); $row = spi_fetch_row($res); if ($row['count'] > 0) { return 0 ; } else { return 1; }; $$;
  • 57. spi functions? Internal functions for interacting with the db ● spi_exec :: execute a query with optional limit. – spi_status :: return status of a previous query. – spi_fetch_row :: return associative array of the – row's results. spi_processed :: return the number of tuples in a – result. spi_rewind :: put the row cursor at the beginning – of the result.
  • 58. CREATE OR REPLACE FUNCTION movie_in_stock(integer) RETURNS Boolean LANGUAGE plphpu AS $$ $sql = quot;SELECT count(*) FROM rental WHERE inventory_id = quot;.$args[0]; $res = spi_exec($sql); $row = spi_fetch_row($res); if ($row['count'] == 0) return 1; $sql = quot;SELECT count(rental_id) FROM inventory LEFT JOIN rental USING (inventory_id) WHERE inventory.inventory_id = quot;.$args[0].quot; AND rental.return_date IS NULLquot;; $res = spi_exec($sql); $row = spi_fetch_row($res); if ($row['count'] > 0) { return 0 ; } else { return 1; }; $$;
  • 59. CREATE OR REPLACE FUNCTION movie_in_stock(integer) RETURNS Boolean LANGUAGE plphpu AS $$ $sql = quot;SELECT count(*) FROM rental WHERE inventory_id = quot;.$args[0]; $res = spi_exec($sql); $row = spi_fetch_row($res); if ($row['count'] == 0) return 1; $sql = quot;SELECT count(rental_id) FROM inventory LEFT JOIN rental USING (inventory_id) WHERE inventory.inventory_id = quot;.$args[0].quot; AND rental.return_date IS NULLquot;; $res = spi_exec($sql); $row = spi_fetch_row($res); if ($row['count'] > 0) { return 0 ; } else { return 1; }; $$;
  • 60. CREATE OR REPLACE FUNCTION movie_in_stock(integer) RETURNS Boolean LANGUAGE plphpu AS $$ $sql = quot;SELECT count(*) FROM rental WHERE inventory_id = quot;.$args[0]; $res = spi_exec($sql); $row = spi_fetch_row($res); if ($row['count'] == 0) return 1; $sql = quot;SELECT count(rental_id) FROM inventory LEFT JOIN rental USING (inventory_id) WHERE inventory.inventory_id = quot;.$args[0].quot; AND rental.return_date IS NULLquot;; $res = spi_exec($sql); $row = spi_fetch_row($res); if ($row['count'] > 0) { return 0 ; } else { return 1; }; $$;
  • 61. PHP Functions Most PHP functions can be used inside ● pl/php functions CREATE OR REPLACE FUNCTION simplefunc(text,text) RETURNS text LANGUAGE plphpu AS $$ return 'Did you know '. ucwords(strrev($args[0])) .' is '. strtolower($args[1]) .' backwards?'; $$; pagila=# select simplefunc('inside out','outside in'); simplefunc ------------------------------------------------------ Did you know Tuo Edisni is outside in backwards? (1 row)
  • 62. PHP Functions CREATE OR REPLACE FUNCTION notsimplefunc() RETURNS text LANGUAGE plphpu AS $$ $sql = quot;select version()quot;; $c = pg_connect(quot;host=10.225.105.53 dbname=template1 user=postgresquot;); $r = pg_query($c,$sql); $v = pg_fetch_result($r,0,0); return $v; $$;
  • 63. PHP Functions pagila=# SELECT notsimplefunc(); nosimplefunc ----------------------------------------------------------------------------------------------------------- PostgreSQL 8.1.1 on i686-redhat-linux-gnu, compiled by GCC gcc (GCC) 3.4.2 20041017 (Red Hat 3.4.2-6.fc3) (1 row) pagila=# SELECT version(); version ------------------------------------------------------------------------------------------------------- PostgreSQL 8.1.1 on i686-redhat-linux-gnu, compiled by GCC gcc (GCC) 4.0.1 20050727 (Red Hat 4.0.1-5) (1 row) Connect to external database Does have scary implications ● ● Normally not recommended But this kind of flexibility can be cool ● ●
  • 64. PHP Functions CREATE OR REPLACE FUNCTION wickedfunc() RETURNS text LANGUAGE plphpu as $$ $c = mysql_connect(quot;10.225.105.94quot;,quot;sakilaquot;); $v = mysql_get_server_info(); return $v; $$;
  • 65. PHP Functions CREATE OR REPLACE FUNCTION wickedfunc() RETURNS text LANGUAGE plphpu as $$ $c = mysql_connect(quot;10.225.105.94quot;,quot;sakilaquot;); $v = mysql_get_server_info(); return $v; $$; pagila=# SELECT wickedfunc(); wickedfunc -------------- 5.1.9-beta (1 row)
  • 66. the PEAR example Can use PEAR modules inside functions ● Walk through example for validating email ● Pagila database ● (http://pgfoundry.org/projects/dbsamples/) Validate package ● (http://pear.php.net/package/Validate)
  • 67. the Pear example CREATE OR REPLACE FUNCTION valid_email(text) RETURNS boolean IMMUTABLE LANGUAGE plphpu AS $$ require_once 'Validate.php'; $validate = new Validate(); return $validate->email(quot;$args[0]quot;,array(“check_domain”=>false,”use_rfc822”=>true)) ? 1 : 0; $$;
  • 68. the Pear example pagila=# SELECT valid_email('xzilla@users.sourceforge.net'); valid_email -------------------- t (1 row) pagila=# SELECT valid_email ('Robert Treat <xzilla@ users . sf . net>'); valid_email --------------------- t (1 row) pagila=# SELECT valid_email('www.brighterlamp.org'); valid_email --------------------- f (1 row)
  • 69. the Pear example Functions may inter-operate with any other ● part of the database system CREATE DOMAIN validemail AS text NOT NULL CHECK ( valid_email(VALUE) );
  • 70. the Pear example Functions may inter-operate with any other ● part of the database system CREATE DOMAIN validemail AS text NOT NULL CHECK ( valid_email(VALUE) );
  • 71. the Pear example Functions may inter-operate with any other ● part of the database system CREATE DOMAIN validemail AS text NOT NULL CHECK ( valid_email(VALUE) );
  • 72. the Pear example pagila=# ALTER TABLE customer ALTER email TYPE validemail ; ALTER TABLE All data must pass through our function ● Validates all data in table ● Validates all data inserts and updates ●
  • 73. the Pear example pagila=# INSERT INTO customer (store_id, first_name, last_name, email, address_id, active) pagila-# VALUES (2,'pete','hache-pee','l33t@aol',40,1); ERROR: value for domain validemail violates check constraint quot;validemail_checkquot; No special syntax needed ● Error messages reference function ● We can tweak rules by modifying the function ●
  • 74. pl/php triggers pl/php functions can be used as triggers too ● Can access new and old data in the table ● PostgreSQL gives us access to special trigger ● specific information
  • 75. pl/php triggers pl/php functions can be used as triggers too ● Can access new and old data in the table ● PostgreSQL gives us access to special trigger ● specific information Example: Log overdue rental returns for ● customers automatically through functions
  • 76. pl/php triggers pagila=# d customer Table quot;public.customerquot; Column | Type | Modifiers -------------+-----------------------------+---------------------------------------------------------------- customer_id | integer | not null default nextval('customer_customer_id_seq'::regclass) store_id | smallint | not null first_name | character varying(45) | not null last_name | character varying(45) | not null email | character varying(50) | address_id | smallint | not null activebool | boolean | not null default true create_date | date | not null default ('now'::text)::date last_update | timestamp without time zone | default now() active | integer | Indexes: quot;customer_pkeyquot; PRIMARY KEY, btree (customer_id) quot;idx_fk_address_idquot; btree (address_id) quot;idx_fk_store_idquot; btree (store_id) quot;idx_last_namequot; btree (last_name) Foreign-key constraints: quot;customer_address_id_fkeyquot; FOREIGN KEY (address_id) REFERENCES address(address_id) ON UPDATE CASCADE ON DELETE RESTRICT quot;customer_store_id_fkeyquot; FOREIGN KEY (store_id) REFERENCES store(store_id) ON UPDATE CASCADE ON DELETE RESTRICT Triggers: last_updated BEFORE UPDATE ON customer FOR EACH ROW EXECUTE PROCEDURE last_updated()
  • 77. pl/php triggers pagila=# d rental Table quot;public.rentalquot; Column | Type | Modifiers --------------+-----------------------------+------------------------------------------------------------ rental_id | integer | not null default nextval('rental_rental_id_seq'::regclass) rental_date | timestamp without time zone | not null inventory_id | integer | not null customer_id | smallint | not null return_date | timestamp without time zone | staff_id | smallint | not null last_update | timestamp without time zone | not null default now() Indexes: quot;rental_pkeyquot; PRIMARY KEY, btree (rental_id) quot;idx_unq_rental_rental_date_inventory_id_customer_idquot; UNIQUE, btree (rental_date, inventory_id, customer_id) quot;idx_fk_inventory_idquot; btree (inventory_id) Foreign-key constraints: quot;rental_customer_id_fkeyquot; FOREIGN KEY (customer_id) REFERENCES customer(customer_id) ON UPDATE CASCADE ON DELETE RESTRICT quot;rental_inventory_id_fkeyquot; FOREIGN KEY (inventory_id) REFERENCES inventory(inventory_id) ON UPDATE CASCADE ON DELETE RESTRICT quot;rental_staff_id_fkeyquot; FOREIGN KEY (staff_id) REFERENCES staff(staff_id) ON UPDATE CASCADE ON DELETE RESTRICT Triggers: last_updated BEFORE UPDATE ON rental FOR EACH ROW EXECUTE PROCEDURE last_updated()
  • 78. pl/php triggers CREATE TABLE overdue_log ( overdue_log_id serial, customer_id integer, days_overdue integer ); Each record gets a logical primary key ● Store the customer id and the number of days ● rental was overdue
  • 79. pl/php triggers CREATE TABLE overdue_log ( overdue_log_id serial, customer_id integer, days_overdue integer ); Each record gets a logical primary key ● Store the customer id and the number of days ● rental was overdue Yes, this table is fake... no FK's, no ● timestamps, etc...
  • 80. pl/php triggers – special variables $_TD[“old”] - Old data being removed from ● table $_TD[“new”] - New data being written to table ● Associative arrays, indexed by field names ● Null values not included ● Other special variables ● trigger name, trigger action, table name, etc... –
  • 81. pl/php trigger function CREATE OR REPLACE FUNCTION watch_overdue() RETURNS trigger LANGUAGE plphpu AS $$ $new =& $_TD['new']; $sql = quot;SELECT rental_date + (rental_duration * '1 day'::interval) as due_date FROM rental INNER JOIN inventory USING (inventory_id) INNER JOIN film USING (film_id) WHERE rental_id =quot;. $new['rental_id']; $rs = spi_exec($sql); $r = spi_fetch_row($rs); continued...
  • 82. pl/php trigger function CREATE OR REPLACE FUNCTION watch_overdue() RETURNS trigger LANGUAGE plphpu AS $$ $new =& $_TD['new']; $sql = quot;SELECT rental_date + (rental_duration * '1 day'::interval) as due_date FROM rental INNER JOIN inventory USING (inventory_id) INNER JOIN film USING (film_id) WHERE rental_id =quot;. $new['rental_id']; $rs = spi_exec($sql); $r = spi_fetch_row($rs); continued...
  • 83. pl/php trigger function continued... pg_raise('notice',$r['due_date']); pg_raise('notice',$new['return_date']); if ($new['return_date'] > $r['due_date']) { /* rental is overdue, we need to convert our dates to php time values, find the difference between them, and then convert that to days */ $dayo = (strtotime($new['return_date']) - strtotime($r['due_date']))/60/60/24; pg_raise('notice',$dayo); $sql = quot;INSERT INTO overdue_log (customer_id,days_overdue) VALUES (quot;.$new['customer_id'].quot;,quot;.$dayo.quot;)quot;; $rs = spi_exec($sql); }; return null; $$;
  • 84. pl/php trigger function continued... pg_raise('notice',$r['due_date']); pg_raise('notice',$new['return_date']); if ($new['return_date'] > $r['due_date']) { /* rental is overdue, we need to convert our dates to php time values, find the difference between them, and then convert that to days */ $dayo = (strtotime($new['return_date']) - strtotime($r['due_date']))/60/60/24; pg_raise('notice',$dayo); $sql = quot;INSERT INTO overdue_log (customer_id,days_overdue) VALUES (quot;.$new['customer_id'].quot;,quot;.$dayo.quot;)quot;; $rs = spi_exec($sql); }; return null; $$;
  • 85. pl/php trigger function continued... pg_raise('notice',$r['due_date']); pg_raise('notice',$new['return_date']); if ($new['return_date'] > $r['due_date']) { /* rental is overdue, we need to convert our dates to php time values, find the difference between them, and then convert that to days */ $dayo = (strtotime($new['return_date']) - strtotime($r['due_date']))/60/60/24; pg_raise('notice',$dayo); $sql = quot;INSERT INTO overdue_log (customer_id,days_overdue) VALUES (quot;.$new['customer_id'].quot;,quot;.$dayo.quot;)quot;; $rs = spi_exec($sql); }; return null; $$;
  • 86. pl/php trigger function continued... pg_raise('notice',$r['due_date']); pg_raise('notice',$new['return_date']); if ($new['return_date'] > $r['due_date']) { /* rental is overdue, we need to convert our dates to php time values, find the difference between them, and then convert that to days */ $dayo = (strtotime($new['return_date']) - strtotime($r['due_date']))/60/60/24; pg_raise('notice',$dayo); $sql = quot;INSERT INTO overdue_log (customer_id,days_overdue) VALUES (quot;.$new['customer_id'].quot;,quot;.$dayo.quot;)quot;; $rs = spi_exec($sql); }; return null; $$;
  • 87. pl/php triggers (the trigger) CREATE TRIGGER watch_overdue AFTER insert or update ON rental FOR EACH row EXECUTE PROCEDURE watch_overdue(); No special syntax needed – Trigger fires on any insert or update – We can tweak rules by modifying the function –
  • 88. pl/php triggers pagila=# INSERT INTO rental pagila-# VALUES (DEFAULT,now() - '1 month'::interval,2792,549,now(),1);
  • 89. pl/php triggers pagila=# INSERT INTO rental pagila-# VALUES (DEFAULT,now() - '1 month'::interval,2792,549,now(),1); NOTICE: plphp: 2006-07-30 11:27:56.854139 NOTICE: plphp: 2006-08-25 11:27:56.854139 NOTICE: plphp: 26 INSERT 0 1 pagila=#
  • 90. pl/php triggers pagila=# INSERT INTO rental pagila-# VALUES (DEFAULT,now() - '1 month'::interval,2792,549,now(),1); NOTICE: plphp: 2006-07-30 11:27:56.854139 NOTICE: plphp: 2006-08-25 11:27:56.854139 NOTICE: plphp: 26 INSERT 0 1 pagila=# SELECT * FROM overdue_log;
  • 91. pl/php triggers pagila=# INSERT INTO rental pagila-# VALUES (DEFAULT,now() - '1 month'::interval,2792,549,now(),1); NOTICE: plphp: 2006-07-30 11:27:56.854139 NOTICE: plphp: 2006-08-25 11:27:56.854139 NOTICE: plphp: 26 INSERT 0 1 pagila=# SELECT * FROM overdue_log; overdue_log_id | customer_id | days_overdue ----------------------+-----------------+---------------- 1| 549 | 26
  • 92. pl/php – one more example CREATE OR REPLACE FUNCTION text_array_to_result(text[]) RETURNS setof text LANGUAGE plphpu AS $$ // TRICKY!! $args[0] refers to the first argument of the function // so $args[0][0] refers to the first value of the array passed into the first argument! $i=0; while ($args[0][$i]) { $ret = $args[0][$i]; return_next($ret); $i++; } #pg_raise('notice',$args[0]); $$;
  • 93. pl/php – one more example CREATE OR REPLACE FUNCTION text_array_to_result(text[]) RETURNS setof text LANGUAGE plphpu AS $$ // TRICKY!! $args[0] refers to the first argument of the function // so $args[0][0] refers to the first value of the array passed into the first argument! $i=0; while ($args[0][$i]) { $ret = $args[0][$i]; return_next($ret); $i++; } #pg_raise('notice',$args[0]); $$;
  • 94. pl/php – one more example CREATE OR REPLACE FUNCTION text_array_to_result(text[]) RETURNS setof text LANGUAGE plphpu AS $$ // TRICKY!! $args[0] refers to the first argument of the function // so $args[0][0] refers to the first value of the array passed into the first argument! $i=0; while ($args[0][$i]) { $ret = $args[0][$i]; return_next($ret); $i++; } #pg_raise('notice',$args[0]); $$;
  • 95. pl/php – one more example pagila=# SELECT * FROM text_array_to_result('{txt arg 1,txt arg 2}'); text_array_to_result ---------------------- txt arg 1 txt arg 2 (2 rows) Works with arrays ● Works for set returning functions ●
  • 96. pl/php – one more example pagila=# SELECT * FROM text_array_to_result('{txt arg 1,txt arg 2}'); text_array_to_result ---------------------- txt arg 1 txt arg 2 (2 rows) Works with arrays ● Works for set returning functions ● Oh yeah... no special syntax :-) ●
  • 97. but wait, there's more! Composite data types ● Working with array types ● Global shared variables ● Polymorphic Arguments ● Polymorphic Return Types ● Composite Types ●
  • 98. pl/php - caveats Rough around the edges ● sometimes uncover segfaults – lots of warnings / notices from php – no in / out parameters (8.1) –
  • 99. pl/php - caveats Rough around the edges ● sometimes uncover segfaults – lots of warnings / notices from php – no in / out parameters (8.1) – Can't call other pl/php functions directly ●
  • 100. pl/php - caveats Rough around the edges ● sometimes uncover segfaults – lots of warnings / notices from php – no in / out parameters (8.1) – Can't call other pl/php functions directly ● Not fully tested against all PHP functions ●
  • 101. pl/php - caveats Rough around the edges ● sometimes uncover segfaults – lots of warnings / notices from php – no in / out parameters (8.1) – Can't call other pl/php functions directly ● Not fully tested against all PHP functions ● Needs some C developers to contribute ●
  • 102. Thanks! Command Prompt, Inc. Alvarro Herrera Alexey Klyukin Greg Sabino-Mullane OmniTI The PHP & PostgreSQL Communities :-)