parseDSN rewrite

[email protected] ("Tomas V.V.Cox") Thu, 01 Mar 2001 17:17:05 +0100
Newsgroups php.pear
Message-ID <[email protected]>
Hello ppl,

Due the problems I had with the DB.php parseDSN method, I decided to
rewrite the function to make it work properly (attached in the msg). All
the dsn formats works good, but there are some considerations:

* Added a new permitted format: empty passwords:

phptype://username:@hostspec/database

* Added new possible formats in database, this is:

phptype://username:@hostspec/database -> database
phptype://username:@hostspec/usr/dbs/test.db -> /usr/dbs/test.db
phptype://username:@hostspec/c:\winpof\test.db -> c:\winpof\test.db

* At the start of the method I've putted:

$dsn=urldecode($dsn);

I think, we shouldn't modify o decode params, this is user stuff, but
ok, it's there.

Probably this function is faster than the original function, because it
mostly use string function rather than regex.

Perhaps that helps,

Tomas V.V.Cox
parseDSN.php (text/plain, 2.7 KB)
<?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

		* @return array with filled values in
		* @author Tomas V.V.Cox <[email protected]>
*/
function parseDSN($dsn){

	if (is_array($dsn)) {
	   	 return $dsn;
	}
	$dsn = urldecode($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
	$points = strpos($dsn,':');
	$arroba = strpos($dsn,'@');
	if (($points !== $false) && ($arroba !== false) &&
		($points < $arroba)){
		$str=substr($dsn,0,$arroba);
		$dsn=substr($dsn, $arroba+1);
		list($parsed['username'],$parsed['password'])=explode(':', $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 (strpos($str,'+') !== false){
		list($parsed['protocol'],$parsed['hostspec'])=explode('+', $str);
	} else {
		$parsed['hostspec'] = $str;
	}

	// Get dabase if any
	// $dsn => database
	if (strlen($dsn)){
		$prep=(strpos($dsn,"/") !== false) ? '/' : '';
		$parsed['database'] = $prep.$dsn;
	}
	return $parsed;
}
?>