wez Mon Nov 28 21:11:40 2005 EDT
Added files: (Branch: PHP_5_1)
/php-src/ext/pdo_pgsql/tests config.inc large_objects.phpt
Modified files:
/php-src/ext/pdo_pgsql package.xml pdo_pgsql.c pgsql_driver.c
pgsql_statement.c php_pdo_pgsql_int.h
/php-src/ext/pdo_pgsql/tests bug_33876.phpt common.phpt
Log:
Added PDO::pgsqlLOBCreate(), PDO::pgsqlLOBOpen() and PDO::pgsqlLOBUnlink().
http://cvs.php.net/diff.php/php-src/ext/pdo_pgsql/package.xml?r1=1.5.2.4&r2=1.5.2.5&ty=u
Index: php-src/ext/pdo_pgsql/package.xml
diff -u php-src/ext/pdo_pgsql/package.xml:1.5.2.4
php-src/ext/pdo_pgsql/package.xml:1.5.2.5
--- php-src/ext/pdo_pgsql/package.xml:1.5.2.4 Sat Nov 26 15:50:07 2005
+++ php-src/ext/pdo_pgsql/package.xml Mon Nov 28 21:11:37 2005
@@ -30,8 +30,8 @@
<license>PHP</license>
<release>
<state>stable</state>
- <version>1.0</version>
- <date>2005-11-26</date>
+ <version>1.0.1</version>
+ <date>2005-11-28</date>
<notes>
Now features native prepared statements and numerous other improvements.
@@ -42,6 +42,8 @@
If you are running on windows, you can download the binary from here:
http://pecl4win.php.net/ext.php/php_pdo_pgsql.dll
+
+Added PDO::pgsqlLOBCreate(), PDO::pgsqlLOBOpen() and PDO::pgsqlLOBUnlink().
</notes>
<filelist>
@@ -57,7 +59,7 @@
</filelist>
<deps>
<dep type="php" rel="ge" version="5.0.3"/>
- <dep type="ext" rel="ge" name="pdo" version="1.0"/>
+ <dep type="ext" rel="ge" name="pdo" version="1.0.2"/>
</deps>
</release>
</package>
http://cvs.php.net/diff.php/php-src/ext/pdo_pgsql/pdo_pgsql.c?r1=1.7.2.6&r2=1.7.2.7&ty=u
Index: php-src/ext/pdo_pgsql/pdo_pgsql.c
diff -u php-src/ext/pdo_pgsql/pdo_pgsql.c:1.7.2.6
php-src/ext/pdo_pgsql/pdo_pgsql.c:1.7.2.7
--- php-src/ext/pdo_pgsql/pdo_pgsql.c:1.7.2.6 Sat Nov 26 15:50:08 2005
+++ php-src/ext/pdo_pgsql/pdo_pgsql.c Mon Nov 28 21:11:37 2005
@@ -16,7 +16,7 @@
+----------------------------------------------------------------------+
*/
-/* $Id: pdo_pgsql.c,v 1.7.2.6 2005/11/26 20:50:08 wez Exp $ */
+/* $Id: pdo_pgsql.c,v 1.7.2.7 2005/11/29 02:11:37 wez Exp $ */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -61,7 +61,7 @@
PHP_RINIT(pdo_pgsql),
PHP_RSHUTDOWN(pdo_pgsql),
PHP_MINFO(pdo_pgsql),
- "1.0",
+ "1.0.1",
STANDARD_MODULE_PROPERTIES
};
/* }}} */
http://cvs.php.net/diff.php/php-src/ext/pdo_pgsql/pgsql_driver.c?r1=1.53.2.1&r2=1.53.2.2&ty=u
Index: php-src/ext/pdo_pgsql/pgsql_driver.c
diff -u php-src/ext/pdo_pgsql/pgsql_driver.c:1.53.2.1
php-src/ext/pdo_pgsql/pgsql_driver.c:1.53.2.2
--- php-src/ext/pdo_pgsql/pgsql_driver.c:1.53.2.1 Thu Nov 24 22:35:04 2005
+++ php-src/ext/pdo_pgsql/pgsql_driver.c Mon Nov 28 21:11:37 2005
@@ -12,11 +12,13 @@
| obtain it through the world-wide-web, please send a note to |
| [EMAIL PROTECTED] so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
- | Author: Edin Kadribasic <[EMAIL PROTECTED]> |
+ | Authors: Edin Kadribasic <[EMAIL PROTECTED]> |
+ | Ilia Alshanestsky <[EMAIL PROTECTED]> |
+ | Wez Furlong <[EMAIL PROTECTED]>
|
+----------------------------------------------------------------------+
*/
-/* $Id: pgsql_driver.c,v 1.53.2.1 2005/11/25 03:35:04 wez Exp $ */
+/* $Id: pgsql_driver.c,v 1.53.2.2 2005/11/29 02:11:37 wez Exp $ */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -108,6 +110,81 @@
}
/* }}} */
+/* {{{ pdo_pgsql_create_lob_stream */
+static size_t pgsql_lob_write(php_stream *stream, const char *buf, size_t
count TSRMLS_DC)
+{
+ struct pdo_pgsql_lob_self *self = (struct
pdo_pgsql_lob_self*)stream->abstract;
+ return lo_write(self->conn, self->lfd, (char*)buf, count);
+}
+
+static size_t pgsql_lob_read(php_stream *stream, char *buf, size_t count
TSRMLS_DC)
+{
+ struct pdo_pgsql_lob_self *self = (struct
pdo_pgsql_lob_self*)stream->abstract;
+ return lo_read(self->conn, self->lfd, buf, count);
+}
+
+static int pgsql_lob_close(php_stream *stream, int close_handle TSRMLS_DC)
+{
+ struct pdo_pgsql_lob_self *self = (struct
pdo_pgsql_lob_self*)stream->abstract;
+ pdo_dbh_t *dbh = self->dbh;
+
+ if (close_handle) {
+ lo_close(self->conn, self->lfd);
+ }
+ efree(self);
+ php_pdo_dbh_delref(dbh TSRMLS_DC);
+ return 0;
+}
+
+static int pgsql_lob_flush(php_stream *stream TSRMLS_DC)
+{
+ return 0;
+}
+
+static int pgsql_lob_seek(php_stream *stream, off_t offset, int whence,
+ off_t *newoffset TSRMLS_DC)
+{
+ struct pdo_pgsql_lob_self *self = (struct
pdo_pgsql_lob_self*)stream->abstract;
+ int pos = lo_lseek(self->conn, self->lfd, offset, whence);
+ *newoffset = pos;
+ return pos >= 0 ? 0 : -1;
+}
+
+php_stream_ops pdo_pgsql_lob_stream_ops = {
+ pgsql_lob_write,
+ pgsql_lob_read,
+ pgsql_lob_close,
+ pgsql_lob_flush,
+ "pdo_pgsql lob stream",
+ pgsql_lob_seek,
+ NULL,
+ NULL,
+ NULL
+};
+
+php_stream *pdo_pgsql_create_lob_stream(pdo_dbh_t *dbh, int lfd, Oid oid
TSRMLS_DC)
+{
+ php_stream *stm;
+ struct pdo_pgsql_lob_self *self = ecalloc(1, sizeof(*self));
+ pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data;
+
+ self->dbh = dbh;
+ self->lfd = lfd;
+ self->oid = oid;
+ self->conn = H->server;
+
+ stm = php_stream_alloc(&pdo_pgsql_lob_stream_ops, self, 0, "r+b");
+
+ if (stm) {
+ php_pdo_dbh_addref(dbh TSRMLS_CC);
+ return stm;
+ }
+
+ efree(self);
+ return NULL;
+}
+/* }}} */
+
static int pgsql_handle_closer(pdo_dbh_t *dbh TSRMLS_DC) /* {{{ */
{
pdo_pgsql_db_handle *H = (pdo_pgsql_db_handle *)dbh->driver_data;
@@ -397,6 +474,124 @@
return pdo_pgsql_transaction_cmd("ROLLBACK", dbh TSRMLS_CC);
}
+/* {{{ string pgSQL::pgsqlLOBCreate()
+ Creates a new large object, returning its identifier. Must be called
inside a transaction. */
+static PHP_METHOD(pgSQL, pgsqlLOBCreate)
+{
+ pdo_dbh_t *dbh;
+ pdo_pgsql_db_handle *H;
+ Oid lfd;
+
+ dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
+ PDO_CONSTRUCT_CHECK;
+
+ H = (pdo_pgsql_db_handle *)dbh->driver_data;
+ lfd = lo_creat(H->server, INV_READ|INV_WRITE);
+
+ if (lfd != InvalidOid) {
+ char *buf;
+ spprintf(&buf, 0, "%lu", lfd);
+ RETURN_STRING(buf, 0);
+ }
+
+ pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "HY000");
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ resource pgSQL::pgsqlLOBOpen(string oid [, string mode = 'rb'])
+ Opens an existing large object stream. Must be called inside a
transaction. */
+static PHP_METHOD(pgSQL, pgsqlLOBOpen)
+{
+ pdo_dbh_t *dbh;
+ pdo_pgsql_db_handle *H;
+ Oid oid;
+ int lfd;
+ char *oidstr;
+ int oidstrlen;
+ char *modestr = "rb";
+ int modestrlen;
+ int mode = INV_READ;
+ char *end_ptr;
+
+ if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|s",
+ &oidstr, &oidstrlen, &modestr, &modestrlen)) {
+ RETURN_FALSE;
+ }
+
+ oid = (Oid)strtoul(oidstr, &end_ptr, 10);
+ if (oid == 0 && (errno == ERANGE || errno == EINVAL)) {
+ RETURN_FALSE;
+ }
+
+ if (strpbrk(modestr, "+w")) {
+ mode = INV_READ|INV_WRITE;
+ }
+
+ dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
+ PDO_CONSTRUCT_CHECK;
+
+ H = (pdo_pgsql_db_handle *)dbh->driver_data;
+
+ lfd = lo_open(H->server, oid, mode);
+
+ if (lfd >= 0) {
+ php_stream *stream = pdo_pgsql_create_lob_stream(dbh, lfd, oid
TSRMLS_CC);
+ if (stream) {
+ php_stream_to_zval(stream, return_value);
+ return;
+ }
+ } else {
+ pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "HY000");
+ }
+ RETURN_FALSE;
+}
+/* }}} */
+
+/* {{{ bool pgSQL::pgsqlLOBUnlink(int oid)
+ Deletes the large object identified by oid. Must be called inside a
transaction. */
+static PHP_METHOD(pgSQL, pgsqlLOBUnlink)
+{
+ pdo_dbh_t *dbh;
+ pdo_pgsql_db_handle *H;
+ long lfd;
+
+ if (FAILURE == zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "l",
+ &lfd)) {
+ RETURN_FALSE;
+ }
+
+ dbh = zend_object_store_get_object(getThis() TSRMLS_CC);
+ PDO_CONSTRUCT_CHECK;
+
+ H = (pdo_pgsql_db_handle *)dbh->driver_data;
+
+ if (1 == lo_unlink(H->server, lfd)) {
+ RETURN_TRUE;
+ }
+ pdo_pgsql_error(dbh, PGRES_FATAL_ERROR, "HY000");
+ RETURN_FALSE;
+}
+
+
+
+static function_entry dbh_methods[] = {
+ PHP_ME(pgSQL, pgsqlLOBCreate, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(pgSQL, pgsqlLOBOpen, NULL, ZEND_ACC_PUBLIC)
+ PHP_ME(pgSQL, pgsqlLOBUnlink, NULL, ZEND_ACC_PUBLIC)
+ {NULL, NULL, NULL}
+};
+
+static function_entry *pdo_pgsql_get_driver_methods(pdo_dbh_t *dbh, int kind
TSRMLS_DC)
+{
+ switch (kind) {
+ case PDO_DBH_DRIVER_METHOD_KIND_DBH:
+ return dbh_methods;
+ default:
+ return NULL;
+ }
+}
+
static struct pdo_dbh_methods pgsql_methods = {
pgsql_handle_closer,
pgsql_handle_preparer,
@@ -410,7 +605,7 @@
pdo_pgsql_fetch_error_func,
pdo_pgsql_get_attribute,
NULL, /* check_liveness */
- NULL /* get_driver_methods */
+ pdo_pgsql_get_driver_methods /* get_driver_methods */
};
static int pdo_pgsql_handle_factory(pdo_dbh_t *dbh, zval *driver_options
TSRMLS_DC) /* {{{ */
@@ -462,7 +657,7 @@
H->pgoid = -1;
dbh->methods = &pgsql_methods;
- dbh->alloc_own_columns = 1;
+ dbh->alloc_own_columns = 0;
dbh->max_escaped_char_length = 2;
ret = 1;
http://cvs.php.net/diff.php/php-src/ext/pdo_pgsql/pgsql_statement.c?r1=1.31.2.4&r2=1.31.2.5&ty=u
Index: php-src/ext/pdo_pgsql/pgsql_statement.c
diff -u php-src/ext/pdo_pgsql/pgsql_statement.c:1.31.2.4
php-src/ext/pdo_pgsql/pgsql_statement.c:1.31.2.5
--- php-src/ext/pdo_pgsql/pgsql_statement.c:1.31.2.4 Thu Nov 24 22:35:04 2005
+++ php-src/ext/pdo_pgsql/pgsql_statement.c Mon Nov 28 21:11:38 2005
@@ -12,11 +12,13 @@
| obtain it through the world-wide-web, please send a note to |
| [EMAIL PROTECTED] so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
- | Author: Edin Kadribasic <[EMAIL PROTECTED]> |
+ | Authors: Edin Kadribasic <[EMAIL PROTECTED]> |
+ | Ilia Alshanestsky <[EMAIL PROTECTED]> |
+ | Wez Furlong <[EMAIL PROTECTED]>
|
+----------------------------------------------------------------------+
*/
-/* $Id: pgsql_statement.c,v 1.31.2.4 2005/11/25 03:35:04 wez Exp $ */
+/* $Id: pgsql_statement.c,v 1.31.2.5 2005/11/29 02:11:38 wez Exp $ */
#ifdef HAVE_CONFIG_H
#include "config.h"
@@ -39,7 +41,6 @@
#define TEXTOID 25
#define OIDOID 26
-
static int pgsql_stmt_dtor(pdo_stmt_t *stmt TSRMLS_DC)
{
pdo_pgsql_stmt *S = (pdo_pgsql_stmt*)stmt->driver_data;
@@ -184,6 +185,12 @@
#if HAVE_PQPREPARE
if (S->stmt_name && param->is_param) {
switch (event_type) {
+ case PDO_PARAM_EVT_FREE:
+ if (param->driver_data) {
+ efree(param->driver_data);
+ }
+ break;
+
case PDO_PARAM_EVT_ALLOC:
/* decode name from $1, $2 into 0, 1 etc. */
if (param->name) {
@@ -224,10 +231,26 @@
php_stream *stm;
php_stream_from_zval_no_verify(stm, ¶m->parameter);
if (stm) {
-
SEPARATE_ZVAL_IF_NOT_REF(¶m->parameter);
-
Z_TYPE_P(param->parameter) = IS_STRING;
-
Z_STRLEN_P(param->parameter) = php_stream_copy_to_mem(stm,
-
&Z_STRVAL_P(param->parameter), PHP_STREAM_COPY_ALL, 0);
+ if (php_stream_is(stm,
&pdo_pgsql_lob_stream_ops)) {
+ struct
pdo_pgsql_lob_self *self = (struct pdo_pgsql_lob_self*)stm->abstract;
+
pdo_pgsql_bound_param *P = param->driver_data;
+
+ if (P == NULL) {
+ P =
ecalloc(1, sizeof(*P));
+
param->driver_data = P;
+ }
+ P->oid =
htonl(self->oid);
+
S->param_values[param->paramno] = (char*)&P->oid;
+
S->param_lengths[param->paramno] = sizeof(P->oid);
+
S->param_formats[param->paramno] = 1;
+
S->param_types[param->paramno] = OIDOID;
+ return 1;
+ } else {
+
SEPARATE_ZVAL_IF_NOT_REF(¶m->parameter);
+
Z_TYPE_P(param->parameter) = IS_STRING;
+
Z_STRLEN_P(param->parameter) = php_stream_copy_to_mem(stm,
+
&Z_STRVAL_P(param->parameter), PHP_STREAM_COPY_ALL, 0);
+ }
} else {
/* expected a stream
resource */
pdo_pgsql_error_stmt(stmt, PGRES_FATAL_ERROR, "HY105");
@@ -308,6 +331,7 @@
{
pdo_pgsql_stmt *S = (pdo_pgsql_stmt*)stmt->driver_data;
struct pdo_column_data *cols = stmt->columns;
+ struct pdo_bound_param_data *param;
if (!S->result) {
return 0;
@@ -324,10 +348,25 @@
case BOOLOID:
cols[colno].param_type = PDO_PARAM_BOOL;
break;
+
+ case OIDOID:
+ /* did the user bind the column as a LOB ? */
+ if (stmt->bound_columns && (
+ SUCCESS ==
zend_hash_index_find(stmt->bound_columns,
+ colno, (void**)¶m) ||
+ SUCCESS ==
zend_hash_find(stmt->bound_columns,
+ cols[colno].name,
cols[colno].namelen,
+ (void**)¶m))) {
+ if (PDO_PARAM_TYPE(param->param_type) ==
PDO_PARAM_LOB) {
+ cols[colno].param_type = PDO_PARAM_LOB;
+ break;
+ }
+ }
+ cols[colno].param_type = PDO_PARAM_INT;
+ break;
case INT2OID:
case INT4OID:
- case OIDOID:
cols[colno].param_type = PDO_PARAM_INT;
break;
@@ -487,9 +526,24 @@
break;
case PDO_PARAM_LOB:
- *ptr = php_pdo_pgsql_unescape_bytea(*ptr,
&tmp_len);
- *len = tmp_len;
- *caller_frees = 1;
+ if (S->cols[colno].pgsql_type == OIDOID) {
+ /* ooo, a real large object */
+ char *end_ptr;
+ Oid oid = (Oid)strtoul(*ptr, &end_ptr,
10);
+ int loid = lo_open(S->H->server, oid,
INV_READ);
+ if (loid >= 0) {
+ *ptr =
(char*)pdo_pgsql_create_lob_stream(stmt->dbh, loid, oid TSRMLS_CC);
+ *len = 0;
+ return *ptr ? 1 : 0;
+ }
+ *ptr = NULL;
+ *len = 0;
+ return 0;
+ } else {
+ *ptr =
php_pdo_pgsql_unescape_bytea(*ptr, &tmp_len);
+ *len = tmp_len;
+ *caller_frees = 1;
+ }
break;
case PDO_PARAM_NULL:
case PDO_PARAM_STR:
http://cvs.php.net/diff.php/php-src/ext/pdo_pgsql/php_pdo_pgsql_int.h?r1=1.13.2.1&r2=1.13.2.2&ty=u
Index: php-src/ext/pdo_pgsql/php_pdo_pgsql_int.h
diff -u php-src/ext/pdo_pgsql/php_pdo_pgsql_int.h:1.13.2.1
php-src/ext/pdo_pgsql/php_pdo_pgsql_int.h:1.13.2.2
--- php-src/ext/pdo_pgsql/php_pdo_pgsql_int.h:1.13.2.1 Thu Nov 24 22:35:04 2005
+++ php-src/ext/pdo_pgsql/php_pdo_pgsql_int.h Mon Nov 28 21:11:38 2005
@@ -12,16 +12,19 @@
| obtain it through the world-wide-web, please send a note to |
| [EMAIL PROTECTED] so we can mail you a copy immediately. |
+----------------------------------------------------------------------+
- | Author: Edin Kadribasic <[EMAIL PROTECTED]> |
+ | Authors: Edin Kadribasic <[EMAIL PROTECTED]> |
+ | Ilia Alshanestsky <[EMAIL PROTECTED]> |
+ | Wez Furlong <[EMAIL PROTECTED]>
|
+----------------------------------------------------------------------+
*/
-/* $Id: php_pdo_pgsql_int.h,v 1.13.2.1 2005/11/25 03:35:04 wez Exp $ */
+/* $Id: php_pdo_pgsql_int.h,v 1.13.2.2 2005/11/29 02:11:38 wez Exp $ */
#ifndef PHP_PDO_PGSQL_INT_H
#define PHP_PDO_PGSQL_INT_H
#include <libpq-fe.h>
+#include <libpq/libpq-fs.h>
#include <php.h>
#define PHP_PDO_PGSQL_CONNECTION_FAILURE_SQLSTATE "08006"
@@ -66,10 +69,7 @@
} pdo_pgsql_stmt;
typedef struct {
- char *repr;
- long repr_len;
- int pgsql_type;
- void *thing; /* for LOBS, REFCURSORS etc. */
+ Oid oid;
} pdo_pgsql_bound_param;
extern pdo_driver_t pdo_pgsql_driver;
@@ -90,6 +90,17 @@
PDO_PGSQL_ATTR_DISABLE_NATIVE_PREPARED_STATEMENT =
PDO_ATTR_DRIVER_SPECIFIC,
};
+struct pdo_pgsql_lob_self {
+ pdo_dbh_t *dbh;
+ PGconn *conn;
+ int lfd;
+ Oid oid;
+};
+
+
+php_stream *pdo_pgsql_create_lob_stream(pdo_dbh_t *stmt, int lfd, Oid oid
TSRMLS_DC);
+extern php_stream_ops pdo_pgsql_lob_stream_ops;
+
#endif /* PHP_PDO_PGSQL_INT_H */
/*
http://cvs.php.net/diff.php/php-src/ext/pdo_pgsql/tests/bug_33876.phpt?r1=1.1.2.4&r2=1.1.2.5&ty=u
Index: php-src/ext/pdo_pgsql/tests/bug_33876.phpt
diff -u php-src/ext/pdo_pgsql/tests/bug_33876.phpt:1.1.2.4
php-src/ext/pdo_pgsql/tests/bug_33876.phpt:1.1.2.5
--- php-src/ext/pdo_pgsql/tests/bug_33876.phpt:1.1.2.4 Mon Oct 17 20:15:02 2005
+++ php-src/ext/pdo_pgsql/tests/bug_33876.phpt Mon Nov 28 21:11:39 2005
@@ -3,6 +3,7 @@
--SKIPIF--
<?php
if (!extension_loaded('pdo') || !extension_loaded('pdo_pgsql')) die('skip not
loaded');
+require dirname(__FILE__) . '/config.inc';
require dirname(__FILE__) . '/../../../ext/pdo/tests/pdo_test.inc';
PDOTest::skip();
?>
http://cvs.php.net/diff.php/php-src/ext/pdo_pgsql/tests/common.phpt?r1=1.1&r2=1.1.2.1&ty=u
Index: php-src/ext/pdo_pgsql/tests/common.phpt
diff -u php-src/ext/pdo_pgsql/tests/common.phpt:1.1
php-src/ext/pdo_pgsql/tests/common.phpt:1.1.2.1
--- php-src/ext/pdo_pgsql/tests/common.phpt:1.1 Thu Jul 7 11:20:06 2005
+++ php-src/ext/pdo_pgsql/tests/common.phpt Mon Nov 28 21:11:39 2005
@@ -5,6 +5,7 @@
if (!extension_loaded('pdo_pgsql')) print 'skip'; ?>
--REDIRECTTEST--
# magic auto-configuration
+# Also update config.inc if you make changes here...
$config = array(
'TESTS' => 'ext/pdo/tests'
http://cvs.php.net/co.php/php-src/ext/pdo_pgsql/tests/config.inc?r=1.1&p=1
Index: php-src/ext/pdo_pgsql/tests/config.inc
+++ php-src/ext/pdo_pgsql/tests/config.inc
http://cvs.php.net/co.php/php-src/ext/pdo_pgsql/tests/large_objects.phpt?r=1.1&p=1
Index: php-src/ext/pdo_pgsql/tests/large_objects.phpt
+++ php-src/ext/pdo_pgsql/tests/large_objects.phpt
--
PHP CVS Mailing List (http://www.php.net/)
To unsubscribe, visit: http://www.php.net/unsub.php