RM - Source Code View

Source Code Viewer

This page lets you view source code from my server. The program uses a brute force code formatter to color code elements. NOTE: I wrote this program while trying to learn the vim text editor. This is not my usual coding style.

Use this select box to select a file.

Hide Lines Numbers

View: sql.php PDO Wrapper - Test

Demonstration of a function that wraps the PDO database.

Formatted Code

Below is the code all formatted with bright colors. The program links to files opened with include() and expands those opened with require(). Clicking on the require line should change visibility.

sql.php PDO Wrapper - Test

001 <!DOCTYPE html> 002 <html lang="en"> 003 <head> 004 <meta charset="UTF-8" /> 005 <meta name="viewport" content="width=device-width, initial-scale=1" /> 006 <meta name="Author" content="Kevin Delaney" /> 007 <meta name="keywords" content="pdo connection, php database connection" /> 008 <meta name="description" content="This is the test page for the sql.php object which I use to contain the PHP PDO Object." /> 009 <title>Test Page for sql.php</title> 010 <link rel="canonical" href="https://yintercept.com/resources/sqlTest.php" /> 011 <link rel="stylesheet" href="rm.css" type="text/css"> 012 </head> 013 <body> 014 <div class="main"> 015 <h2>sql Test Page</h2> 016 <p>People often confuse the term "object" and "class." Originally, the term "object design" simply meant grouping procedures and data into a cohesive structures called "objects." The "class" contruct was created for an implementation of Object Oriented Programming called "C for Classes" by Bjarne Stroustrup. C++ was optimized for creating GUI interfaces on desktop computers.</p> 017 <p>The World Wide Web is not a desktop computer. The rigid class structure adopted by PHP impedes development; So, I created a free form object which I placed in the sql.php file. I call this approach <a href="https://yintercept.com/resources/">The Resource Model</a>.</p> 018 <p>This is a test page for sql.php. Use the Code Viewer to see the test. The Test Results are below the dotted line.</p> 019 <hr style="border: 2px dotted #000"> 020 <h3>Test Results</h3> 021 <p>These are tests results for the free form sql object. NOTE: this object requires the <a href="https://yintercept.com/resources/msgTest.php">msg Notification Object</a>.</p> 022 <?php 023 /** 024 * sqlTest.php is a test script for the sql.php object. 025 * Yes, even though it doesn't use a rigid class structure, it is an object. 026 * This link shows the test results: 027 * @see https://yintercept.com/resources/sqlTest.php 028 * 029 * The sql.php object uses the msg.php notification object to report errors. 030 * This scription requires the msg.php object: 031 * @see https://yintercept.com/resources/msgTest.php 032 * 033 * @copyright 2015 kd 034 */ 035 include('/var/www/php/msg.php');
require('/var/www/php/sql.php');
001 <?php 002 003 /** 004 * The sql functions connect with the database using PDO and PDOStatement. 005 * NOTE, you will need to manually edit dbConn to configure the connections. 006 * 007 * @package ResourceModel 008 * @copyright 2002-2016 Kevin Delaney 009 * @license https://yintercept.com/resources/license.html 010 * @see https://yintercept.com/resources 011 * @see https://yintercept.com/resources/view.php?script=1 Source Code 012 * @version 0.0.10 013 * 014 * These are the primary functions: 015 * sqlValue() returns a single value from the database 016 * sqlRow() returns a single row from the database. 017 * sqlArr() returns a 2D array with full result set. 018 * sqlLoop @see https://yintercept.com/resources/view.php?script=10 019 * dbConn() holds the PDO Connect object. It has some additional functions: 020 * Call it with DB_BEGIN, DB_ROLLBACK & DB_COMMIT for transactions 021 * "+dbname" will run an 'ATTACH DATABASE' command 022 * DB_INSERT_ID will return the last insert id 023 * The function returns a PDOStatement if you want one of those. 024 * 025 */ 026 027 const SDB_PATH = '/var/www/db/'; // Location of my SQLite3 databases. 028 const DB_MAIN = 'main'; // name of your primary database 029 // dbConn will process these transactions 030 const DB_INSERT_ID =1; // returns last insert id 031 const DB_BEGIN = 3; // Begin a transaction 032 const DB_ROLLBACK = 4; // rollback a database transaction 033 const DB_COMMIT = 5; // commit a database transaction 034 const DB_CLOSE = 6; // closes connection, logs stats & returns dbCnt. 035 const DB_CNT = 7; // dbComm restures statement count. 036 037 // used by sqlRow() 038 const DB_CHK = 100; 039 const DB_MAX_ROWS = 2000; 040 041 // directives for sqlExec 042 const DB_ONE_MAX = 64; // rollback if more than one row updated 043 const DB_ROWCOUNT = 10; // return the row count 044 const DB_LAST_ID = 1; // same as DB_INSERT_ID 045 include('/var/www/php/cnx.php'); 046 /** 047 * dbConn is a database connection factory that maintains an array of 048 * connections and returns PDOStatements to sql requests. 049 * Currently, I am hard coding the connectson in deConn. 050 * in a future release, connection information will be in an array 051 * 052 * @param string $sql is either SQL command or a short cut code. 053 * @param string $dbi identifies the database to use. 054 * @return mixed[] returns a PDOStatement for SQL command or info related to call. 055 */ 056 057 function dbConn($dbi,$sql) { 058 static $dbh = array(); // array holds the PDO objects. 059 static $dbCnt = 0; // counts calls to the database 060 static $dbTrace = ''; // holds a trace string. 061 /** register your conections here. The values of the array are: 062 * @param string dbnam -- give each db a unique name. Use 'main' for default. 063 * @param integer status starts as 0. Is 1 if connected and -1 if failed. 064 * @param string dsn is the Data Name Source for the connection 065 * @param string user is the database user name 066 * @param string pwd is the password. 067 */ 068 static $connArr = array( 069 DB_MAIN=>['status'=>0,'dsn'=>'sqlite:'.SDB_PATH.'main.db','user'=>'','pwd'=>''], 070 'log'=>['status'=>0,'dsn'=>'sqlite:'.SDB_PATH.'log.db','user'=>'','pwd'=>''], 071 'ele'=>['status'=>0,'dsn'=>PGSQL_CONN,'user'=>null,'pwd'=>null], 072 'invalid'=>['status'=>0,'dsn'=>'whatever','user'=>'bonzo','pwd'=>'letmein']); 073 // I've defined four databases. ele is hosted by http://www.elephantsql.com 074 // the last database is a mistake ... used to test db failures. 075 076 $rv = false; 077 $dbCnt++; 078 $stmt = false; 079 080 try { 081 // verify dbi exists in the index. 082 if (isset($connArr[$dbi])) { 083 if ($connArr[$dbi]['status'] == -1) throw new Exception('No Database Connection.'); 084 } else { 085 throw new Exception('Connection "'.$dbi.'" does not exist.'); 086 } 087 if ($connArr[$dbi]['status']==0) { 088 // connect to the database 089 try { 090 $dbh[$dbi] = new PDO($connArr[$dbi]['dsn'],$connArr[$dbi]['user'],$connArr[$dbi]['pwd']); 091 $connArr[$dbi]['status'] = 1; 092 } catch(PDOException $e) { 093 // record error and set DB_ACTIVE to DB_NONE. 094 $connArr[$dbi]['status'] = -1; 095 // log database connection faxlure in a file 096 file_put_contents(SDB_PATH.'pdoerr.txt', $dbi.' //'.$_SERVER['REQUEST_TIME'].' '.$e->getMessage(), FILE_APPEND | LOCK_EX); 097 throw new Exception('Database connection '.$dbi.' failed.'); 098 } 099 } 100 // We can add little short cuts here. such as +str Attaches a database 101 if (substr($sql,0,1)=='+') { 102 if (substr_count($sql,' ')==0) { 103 $asql = 'ATTACH DATABASE '.$dbh[$dbi]->quote(SDB_PATH.substr($sql,1).'.db').' AS '.$dbh[$dbi]->quote(substr($sql,1)); 104 $dbh[$dbi]->exec($asql); 105 $dbTrace+='A'; 106 $rv = true; 107 } 108 } elseif (substr($sql,0,1) == '^') { 109 $rv = $dbh[$dbi]->quote(substr($sql,1)); 110 } elseif ($sql==DB_INSERT_ID) { 111 $rv = $dbh[$dbi]->lastInsertId(); 112 } elseif ($sql == DB_CNT) { 113 $rv = --$dbCnt; // return current dbCnt (minus this call) 114 } elseif ($sql==DB_CLOSE) { 115 $dbh[$dbi]=null; 116 $dbErrors=false; 117 $rv=$dbCnt; 118 // store a trace of page for later analysis. 119 // $page_id = 0; // will populate later. 120 msgLog('dbTrace',[0,$dbTrace]); 121 } elseif ($sql==DB_BEGIN) { 122 if ($dbh[$dbi]->inTransaction()) { 123 msgComment($dbi.' is already in transaction mode.'); 124 } else { 125 $dbh[$dbi]->beginTransaction(); 126 } 127 $rv = true; 128 } elseif ($sql==DB_ROLLBACK) { 129 if ($dbh[$dbi]->inTransaction()) { 130 $dbh[$dbi]->rollBack(); 131 } else { 132 msgComment('Rollback outside a transaction'); 133 } 134 $rv = true; 135 } elseif ($sql==DB_COMMIT) { 136 if ($dbh[$dbi]->inTransaction()) { 137 $dbh[$dbi]->commit(); 138 } else { 139 msgComment('Attempting to commit outside transaction.'); 140 } 141 $rv = true; 142 } else { 143 // return an unexecuted prepared statement to call procedure. 144 $dbTrace.=substr($sql,0,1); // add first letter of command to trace. 145 $rv = $dbh[$dbi]->prepare($sql); 146 } 147 } catch (Exception $e) { 148 msgError('PDO says: '.$e->getMessage()); 149 $rv = false; 150 } 151 return $rv; 152 } 153 154 /** 155 * sqlValue returns a single value from the database. 156 * @param string $sql is a SQL SELECT command 157 * @param array $arr holds parameters for the SQL command 158 * @return string The function returns the first column of first row of the result 159 */ 160 161 function sqlValue($sql,$arr=[],$dbi=DB_MAIN) { 162 $stmt = dbConn($dbi,$sql); 163 // return an array of zeros on failure. 164 $rv = ''; // returns a blank space on error 165 if (is_object($stmt)) { 166 if (!is_array($arr)) { 167 $tst = $arr; 168 // no need to get huffy is some forgot the brackets to make it an array. 169 if (is_string($tst) or is_numeric($tst)) { 170 $arr=[$tst]; 171 // msgComment('sqlValue - string to array'); 172 } else { 173 msgError('In valid parameter for sqlValue()'); 174 } 175 } 176 if ($stmt->execute($arr)) { 177 $row = $stmt->fetch(PDO::FETCH_NUM); 178 $rv = (isset($row[0]))? $row[0] :''; 179 } else { 180 msgError('sqlValue execute failed'); 181 msgComment($sql.'<br />Parameters = '.implode('|',$arr)); 182 } 183 } else { 184 // this should only happen with a bad SQL statement 185 msgError('sqlValue() call failed. call #'.dbConn(DB_MAIN,DB_CNT)); 186 msgComment($dbi.' '.$sql); 187 // msgComment('RV Datatype is '.gettype($stmt)); 188 } 189 return $rv; 190 } 191 192 /** sqlRow() retruns a row for a SQL command. The command buffers PDOStatement 193 * You can get multiple rows and use function in some loops 194 * Use sqlLoop for complex loops. 195 * @param string $sql is a SQL select command. If null; returns next row of last 196 * command. If $sql==DB_CHK it checks to see if their is a next row. 197 * @param array $arr holds variables for the SQL statement 198 * @param integer $fetchStyle determines the PDO fetch style 199 * @return mixed[] Function returns an array for sql calls or boolean for chk. 200 */ 201 202 function sqlRow($sql=null,$arr=null,$dbi=DB_MAIN,$fetchStyle=PDO::FETCH_NUM) { 203 static $stmt=null; 204 static $style = ''; 205 static $chkCnt = 0; 206 static $chkVal = false; 207 208 209 $rv = [false,0,0,0,0,0,0,0,0,0,0,0,0,0]; 210 if ($sql == DB_CHK) { 211 $rv = ($chkCnt++ > DB_MAX_ROWS )? false : $chkVal; 212 } elseif ($sql == null) { 213 // get the next row from the existing counter. 214 $rv = $stmt->fetch($fetchStyle); 215 if ($rv===false) { 216 $rv = [false,0,0,0,0,0,0,0,0,0,0,0,0,0]; 217 $chkVal = false; 218 } else { 219 $chkVal = true; 220 } 221 } else { 222 // get and execute a PDOStatement 223 $stmt = dbConn($dbi,$sql); 224 $style = $fetchStyle; 225 if (gettype($stmt) == 'object') { 226 if ($stmt->execute($arr)) { 227 $rv = $stmt->fetch($fetchStyle); 228 if ($rv===false) { 229 $rv = [false,0,0,0,0,0,0,0,0,0,0,0,0]; 230 $chkVal = false; 231 } else { 232 $chkVal = true; 233 } 234 } else { 235 $stmt = null; 236 msgError('SQL execute failed'); 237 msgComment($sql); 238 msgComment('Parameters = '.implode('|',$arr)); 239 } 240 } else { 241 // this should only happen with a bad SQL statement 242 msgError('SQL call failed.'); 243 msgComment($sql); 244 msgComment('RV Datatype is '.gettype($stmt)); 245 } 246 } 247 return $rv; 248 } 249 250 251 /** 252 * sqlAll() returns the entire result set as a two dimensional array. 253 * @param string $sql is a SQL SELECT Statement 254 * @param array The $arr array holds values for for the SQL statement 255 * @param integer $fetchStyle is a PDO::FETCH style option 256 * @param array function always returns an array. 257 */ 258 259 function sqlAll($sql,$arr,$dbi=DB_MAIN,$fetchStyle=PDO::FETCH_NUM) { 260 $stmt = dbConn($dbi,$sql); 261 // return an array of zeros on failure. 262 $rv = array(); // returns a blank space on error 263 if (is_object($stmt)) { 264 if ($stmt->execute($arr)) { 265 // I break out of the function to avoid making an extra copy of results 266 return $stmt->fetchAll($fetchStyle); 267 } else { 268 msgError('SQL execute failed'); 269 msgComment($sql.'<br />Parameters: '.implode('|',$arr)); 270 } 271 } else { 272 // this should only happen with a bad SQL statement 273 msgError('SQL call failed.'); 274 msgComment($sql.'<br />RV Datatype is '.gettype($stmt)); 275 } 276 // successful calls return results straignt from driver. 277 return array(); // returns empty array on failure 278 } 279 /** 280 * sqlExec() execute a DML SQL command such as INSERT OR UPDATE 281 * @param string $sql is the SQL command to upddate 282 * @param array $arr contains variables for the SQL 283 * @param integer $directive determines the output of the command The default 284 is to return a row. DB_LAST_ID returns the last insert id. 285 DB_ONE_MAX rollsback transacation if it affects more than one row. 286 * @param string $successMsg is printed on cuccesful execution. 287 Program replaces %ID with insert id and %RS or %RC with row count. 288 * @param string $failureMsg is printed on failure of the statement 289 * @output db Updates the database 290 * @return either the row count or insert id based on $directive 291 */ 292 293 function sqlExec($sql,$arr,$dbi=DB_MAIN,$successMsg='',$failureMsg='',$directive=0) { 294 if ($directive==0) $directive = (substr($sql,0,6) == 'INSERT')? DB_INSERT_ID : DB_ROWCOUNT; 295 if ($directive == DB_ONE_MAX) dbConn($dbi,DB_BEGIN); 296 $stmt = dbConn($dbi,$sql); 297 $rv = 0; // returns rows affected. 298 if (is_object($stmt)) { 299 if ($stmt->execute($arr)) { 300 // prepare message. 301 $rv = $stmt->rowCount(); // rowcount is the default return value. 302 $rowStr = $rv.' rows'; 303 if ($directive == DB_ONE_MAX) { 304 if ($rv > 1) { 305 msgError('SQL Warning. '.$rowStr.' affected on single row query.<br />Rolling back transaction.'); 306 dbConn($dbi,DB_ROLLBACK); 307 msgComment('Rolled back: '.$sql); 308 309 } else { 310 dbConn($dbi,DB_COMMIT); 311 } 312 } 313 if ($rv == 0) { 314 $rowStr = 'no rows'; 315 } elseif ($rv == 1) { 316 $rowStr = '1 row'; 317 } 318 $insertId = dbConn($dbi,DB_INSERT_ID); 319 if ($successMsg != '') msgNote(str_replace(['%ID','%RS','%RC'],[$insertId,$rowStr,$rv],$successMsg)); 320 if ($directive == DB_INSERT_ID) $rv = $insertId; 321 } else { 322 msgError('SQL Exec: '.$failureMsg); 323 msgComment($sql.'<br />Parameters = '.implode('|',$arr)); 324 } 325 } else { 326 // this should only happen with a bad SQL statement 327 msgError('SQL Call: '.$failureMsg); 328 msgComment($sql.'<br />Return Datatype is '.gettype($stmt)); 329 } 330 return $rv; 331 } 332 /** 333 * I use a fair number of sequences which I maintain in a file called Seq_Def 334 * @param string seq_nm is the name of the sequence. 335 * @param boolen if true, wrap calls in BEGIN/COMMIT Transaction 336 * @return integer is -1 on failure or incremented sequence 337 */ 338 function getSeq($seq_nm,$commit=true) { 339 $rv = -1; 340 if ($commit) dbConn(DB_MAIN,DB_BEGIN); 341 $seq=sqlValue('SELECT seq+1 FROM Seq_Def WHERE seq_nm=?',[$seq_nm]); 342 if ($seq>0) { 343 if (sqlExec('UPDATE Seq_Def SET seq=? WHERE seq_nm=?',[$seq,$seq_nm])==1) { 344 $rv=$seq; 345 } else { 346 msgError('Failed to fetch sequence <b>'.$seq_nm.'</b>'); 347 } 348 } else { 349 msgError('Sequence <b>'.$seq_nm.'</b> is undefined.'); 350 } 351 if ($commit) dbConn(DB_MAIN,DB_COMMIT); 352 return $rv; 353 } 354 355 356 357 ?>
// End Require
036 037 $timeArr=array(); 038 $timeArr[]=['Finish Setup', microtime(true)]; 039 $GLOBALS['msg']['debugMode'] = true; // display the debug messages. 040 echo '<h3>sqlValue Test</h3>'; 041 echo '<p>The first test will use sqlValue to draw this sites name from the main database. I will format the link in sqLite3:</p>'; 042 // Since sqlValue outputs a string I can embed it in a string. 043 echo '<p>My Site Name is: '.sqlValue('SELECT site_nm FROM Web_Site WHERE site_id=?',[0]).'. '; 044 // In this second test. I format a URL in SQL and display it inline. 045 // I have to escape the quotes for PHP 046 $sql="SELECT '<a href=\"'||domain_nm||'\">'||subject_nm||'</a>' as 'Link' 047 FROM Web_Site WHERE site_id=?"; 048 echo 'I was born in '.sqlValue($sql,36).'. '; 049 // Notice how I forgot to put braces around 36. sqlValue fixed my mistake. 050 // I will use sqlRow() to extract a two column arrry and build my own link. 051 $sql = 'SELECT domain_nm, subject_nm FROM Web_Site WHERE site_id = ?'; 052 list($site_url, $subject_nm) = sqlRow($sql,[9]); 053 echo 'I am currently serving time in <a href="'.$site_url.'">'.$subject_nm.'</a>.</p>'; 054 echo 'The function getSeq() draws a named sequence from the table. Let\' run getSeq(\'test\') to see if it works: '.getSeq('test').'</p>'; 055 echo '<p>I often make crazy typos when I am programming. I will make a bad SQL statement and use msgNote() to display the error. You should see an error message followed by debug note.</p>'; 056 $timeArr[]=['sqlValue Test', microtime(true)]; 057 sqlValue('SELECT important_info FROM Crazy_Typo WHERE id = ?',[1]); 058 msgHTML(); 059 $timeArr[]=['Typo Test [rem]', microtime(true)]; 060 // reset the the error toggle. 061 $GLOBALS['msg']['isOkay'] = true; 062 echo '<p>In the next test, I will attach the code database and see how many times people have viewed the <a href="https://yintercept.com/resources/view.php?script=3">sql Code Viewer Page</a>.'; 063 // the + call to dbConn attaches a local SQLLite3 database. 064 dbConn(DB_MAIN,'+code'); 065 echo ' It\'s been viewed '.sqlValue('SELECT hit_cnt FROM code.Code_Viewer WHERE code_id=?',[3],DB_MAIN).' times.</p>'; 066 msgHTML(); 067 $timeArr[]=['Attach DB Test', microtime(true)]; 068 echo '<h3>Test sqlAll() Against a Romote Database</h3>'.PHP_EOL; 069 echo '<p>The next code will test sqlAll(). This funnction selects an entire array. To make the test interesting, I created a remote postgres database with <a href="https://www.elephantsql.com/">elephantSQL.com</a>. This data is stored several hundred miles aways.</p>'; 070 // I registered a remode DB with elephantSQL.com which has the local name ele. 071 $arr=sqlAll('SELECT * FROM Test_Table ORDER BY test_id LIMIT 3',[],'ele'); 072 // let's make a quick table. 073 $rCnt = count($arr); 074 echo '<table style="margin: 4px auto; padding: 4px"> 075 <tr style="bottom-border: 2px solid #000"><th>test_id</th><th>test_nm</th><th>hit_cnt</th></tr>'.PHP_EOL; 076 for ($i=0; $i<$rCnt; $i++) { 077 echo '<tr><td>'.$arr[$i][0].'</td><td style="border-right: 2px solid #000; border-left: 2px solid #000">'.$arr[$i][1].'</td><td>'.$arr[$i][2].'</td></tr>'.PHP_EOL; 078 } 079 echo '</table>'; 080 echo '<h3>Updating with sqlExec()</h3>'; 081 echo '<p>Wow, that was fun. I can access data locally and across the country with the same driver. I know. In this next test, I will use sqlExec() to increment the counter in row two.</p>'; 082 // the directive tells sqlExec what to return. The default is to return rowcount 083 sqlExec('UPDATE Test_Table SET hit_cnt = hit_cnt+1 WHERE test_id=?',[2],'ele','Updated %RS on remote table.','Error updating remote table'); 084 echo '<p><b>msgNote</b>() will tell us if the operation was successful. I love msgNote. I run it after every sql statement when I am writing new code. It should say we updated one row.</p>'.PHP_EOL; 085 msgHTML(); 086 echo '<p>sqlValue() says the value of row two is now: '.sqlValue('SELECT hit_cnt FROM Test_Table WHERE test_id = ?',[2],'ele').'.</p>'.PHP_EOL; 087 $timeArr[]=['Remote Database Test', microtime(true)]; 088 echo '<p>The DB_ONE_MAX directive tells sqlExec to rullback if it updates more than one entry. I try to update three rows. It should rollback. The test should scream a warning at me, then a debug message showing my buggy script.</p>'; 089 sqlExec('UPDATE Test_Table SET hit_cnt = 1 WHERE test_id < ?',[4],'ele','Updated #RS.','multi-update',DB_ONE_MAX); 090 msgHTML(); 091 $GLOBALS['msg']['isOkay'] = true; 092 echo '<p>I will try to rollback and rollback without an active transaction. I will give a warning if the rollback fails and a debug comment if the commit fails.</p>'; 093 dbConn('ele',DB_CLOSE); // close resmote connection. 094 dbConn(DB_MAIN,DB_COMMIT); 095 dbConn(DB_MAIN,DB_ROLLBACK); 096 msgHTML(); 097 echo '<h2>dbConn() as a PDOStatement Factory</h2> 098 <p>The <b>sqlExec</b>() function is not really necessary. A more efficient approach is to draw a prepared PDOStatement directly from <b>dbConn</b>(). The following pseudo code uses two PDOStatements concurrently in a complex loop structure:</p> 099 <pre> 100 $sql = \'UPDATE Table ...\'; // some SQL Statement 101 $sql2 = \'INSERT INTO Table ... \'; // a statement for an inner loop 102 $arr = array(); // appropriate data for SQL. 103 $stmt = dbConn(\'main\',$sql); 104 $inner = dbConn(\'main\',$sql2); 105 while ($condition) { 106 // I create message for outer loop. 107 $arr = [ data for outer loop ]; 108 msgToggle($stmt->execute($arr,\'Success Message\',\'Failure Message\'); 109 while (inner condition) { 110 $innerArr = [ data for inner loop ]; 111 $inner->execute($innerArr); 112 } 113 } 114 </pre> 115 <p>I do not believe that functions are superior to objects. The problem I face is simply that database connection needs to be global; So, I encapsulate the PDO object in a function; so that I can generate PDOStatement Objects at will throughout the program.</p> 116 <h2>In Closing</h2> 117 <p>PHP closes all objects at the end of the script; However it is good practice to close connections.</p> 118 <p>I will now close the connections. This test session executed '.dbConn(DB_MAIN,DB_CLOSE).' sql commands. The next block shows script execution times. The calls to the remote server took up most of the time.'; 119 $timeArr[]=['DB_ONE_MAX & Rollback Test', microtime(true)]; 120 $cnt = count($timeArr); 121 $hold = $_SERVER["REQUEST_TIME_FLOAT"]; 122 echo '<table style="margin: 4px auto"> 123 <tr><th>Break</th><th>Script Time</th><th>Diff</th></tr>'.PHP_EOL; 124 for ($i=0;$i<$cnt;$i++) { 125 echo '<tr><td>'.$timeArr[$i][0]; 126 echo '</td><td style="left-border: 2px solid #000; border-right: 2px solid #000">'.($timeArr[$i][1] - $_SERVER["REQUEST_TIME_FLOAT"]); 127 echo '</td><td>'.(number_format($timeArr[$i][1] - $hold,7)).'</td></tr>'.PHP_EOL; 128 $hold= $timeArr[$i][1];; 129 } 130 echo '</table>'; 131 ?> 132 </div> 133 <p style="text-align: center"><a href="http://blog.yintercept.com" style="color: #ff8">blog</a> 134 ~ <a href="http://CommunityColor.com" style="color: #ff8">Community Color</a> 135 </p> 136 </body> 137 </html>

Use "view source" from your browser to grab the output. Feel free to link to this project and check out the Resource Model for information on PHP coding or my tumblr blog for picture of Arizona, Colorado or Utah.

File last modified at January 07 2016 17:04:40.. This page has been viewed 1372 Times.

Record of Revisions
RevbyDateDescription
0.3kd2016-01-13Changed default on sqlExec() to return last insert id on INSERT commands and row count on updates.
0.2kd2016-01-07Added the getDef Function to increment named sequences.

blog ~ Resource Model ~ links