parseDSN ... again

[email protected] ("Tomas V.V.Cox") Sat, 10 Mar 2001 20:09:29 +0100
Newsgroups php.pear
Message-ID <[email protected]>
--------------E27732D58DB31C52B9B76EC8
Content-Type: text/plain; charset=us-ascii
Content-Transfer-Encoding: 7bit

Hi,

Some days ago I posted here a new version of the DB::parseDSN method.
Recently I found some bugs on it, so I corrected them. For ensure that
it will work as espected in all cases I also post here a test battery
(test.php file).

Changes from the previous version:

- You can now put better empty passwords:
phptype://username@hostspec

- User errors are better handled

- Database files formats:
// Name
phptype://hostspec/database => database
// Unix File
phptype://hostspec//usr/dbs/user.db => /usr/dbs/user.dbs
// Win File
phptype://hostspec/c:\win\fails.db => c:\win\fails.db

- Removed urldecode(), for not disturbing '+' chars. Users must manual
decode what they need.

It could be very nice for me if someone can review it and say if the
contribution fits in pear, or if there is something missing/wrong.

Tomas V.V.Cox
--------------E27732D58DB31C52B9B76EC8
Content-Type: text/plain; charset=us-ascii;
 name="parseDSN.php"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="parseDSN.php"

<?php
/*
* Parse a data source name
*
* @param $dsn string Data Source Name to be parsed
*
* @return array an associative array with the following keys:
*
* phptype: Database backend used in PHP (mysql, odbc etc.)
* dbsyntax: Database used with regards to SQL syntax etc.
* protocol: Communication protocol to use (tcp, unix etc.)
* hostspec: Host specification (hostname[:port])
* database: Database to use on the DBMS server
* username: User name for login
* password: Password for login
*
* The format of the supplied DSN is in its fullest form:
*
*  phptype(dbsyntax)://username:password@protocol+hostspec/database
*
* Most variations are allowed:
* phptype://username:password@protocol+hostspec:110//usr/db/user.db
* phptype://username:password@hostspec/database
* phptype://username:password@hostspec
* phptype://username@hostspec
* phptype://hostspec/database
* phptype://hostspec
* phptype(dbsyntax)
* phptype
*
* @author Stig Bakken <[email protected]> (original)
* @author Tomas V.V.Cox <[email protected]> (rewrite)
*/
function parseDSN($dsn){

	if (is_array($dsn)) {
	   	 return $dsn;
	}
	$parsed = array(
	   	 "phptype"  => false,
	   	 "dbsyntax" => false,
	   	 "protocol" => false,
	   	 "hostspec" => false,
	   	 "database" => false,
	   	 "username" => false,
	   	 "password" => false
	);
	// Find phptype & dbsyntax
	if (($pos = strpos($dsn,"://")) !== false){
		$str=substr($dsn, 0, $pos);
		$dsn=substr($dsn, $pos+3);
	} else {
		$str = $dsn;
		$dsn = '';
	}
	// Get phptype & dbsyntax
	// $str => phptype(dbsyntax)
	if (preg_match("|^([^(]+)\(([^(]*)\)$|", $str, $arr)){
		$parsed['phptype'] = $arr[1];
		$parsed['dbsyntax'] = $arr[2];
	} else {
		$parsed['phptype'] = $str;
	}
	if (!strlen($dsn)){
		return $parsed;
	}
	// Get if find: username & password
	// $dsn => username:password@protocol+hostspec/database
	if (($at = strpos($dsn,'@')) !== false){
		$str=substr($dsn,0,$at);
		$dsn=substr($dsn, $at+1);
		if (($pos=strpos($str,':')) !== false){
			$parsed['username'] = substr($str,0,$pos);
			$parsed['password'] = substr($str,$pos+1);
		} else {
			$parsed['username'] = $str;
		}
	}
	// Find protocol + hostspec
	// $dsn => protocol+hostspec/database
	if (($pos=strpos($dsn,"/")) !== false){
		$str=substr($dsn,0,$pos);
		$dsn=substr($dsn,$pos+1);
	} else {
		$str=$dsn;
		$dsn='';
	}
	// Get protocol + hostspec
	// $str => protocol+hostspec
	if (($pos=strpos($str,'+')) !== false){
		$parsed['protocol'] = substr($str,0,$pos);
		$parsed['hostspec'] = substr($str,$pos+1);
	} else {
		$parsed['hostspec'] = $str;
	}
	// Get dabase if any
	// $dsn => database
	if (strlen($dsn)){
		$parsed['database'] = $dsn;
	}
	return $parsed;
}
?>

--------------E27732D58DB31C52B9B76EC8
Content-Type: text/plain; charset=us-ascii;
 name="test.php"
Content-Transfer-Encoding: 7bit
Content-Disposition: inline;
 filename="test.php"

<?php
include ("./parseDSN.php");
$dsn[]='phptype://username:password@protocol+hostspec:110//dbs/user.db';
$dsn[]='phptype://username:password@hostspec/database';
$dsn[]='phptype://username:password@hostspec';
$dsn[]='phptype://username@hostspec';
$dsn[]='phptype://hostspec/database';
$dsn[]='phptype://hostspec';
$dsn[]='phptype(dbsyntax)';
$dsn[]='phptype';
// broken type
$dsn[]='phptype()://:password@@protocol++hostspec:110/c:\usr\user.db';
foreach ($dsn as $d){
	echo "$d\n";
	print_r(parseDSN($d));
}
?>

--------------E27732D58DB31C52B9B76EC8--