Documentation TYPO3 par Ameos |
00001 <?php 00002 /*************************************************************** 00003 * Copyright notice 00004 * 00005 * (c) 2004-2005 Kasper Skaarhoj (kasperYYYY@typo3.com) 00006 * All rights reserved 00007 * 00008 * This script is part of the TYPO3 project. The TYPO3 project is 00009 * free software; you can redistribute it and/or modify 00010 * it under the terms of the GNU General Public License as published by 00011 * the Free Software Foundation; either version 2 of the License, or 00012 * (at your option) any later version. 00013 * 00014 * The GNU General Public License can be found at 00015 * http://www.gnu.org/copyleft/gpl.html. 00016 * A copy is found in the textfile GPL.txt and important notices to the license 00017 * from the author is found in LICENSE.txt distributed with these scripts. 00018 * 00019 * 00020 * This script is distributed in the hope that it will be useful, 00021 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00022 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00023 * GNU General Public License for more details. 00024 * 00025 * This copyright notice MUST APPEAR in all copies of the script! 00026 ***************************************************************/ 00133 class t3lib_DB { 00134 00135 00136 // Debug: 00137 var $debugOutput = FALSE; // Set "TRUE" if you want database errors outputted. 00138 var $debug_lastBuiltQuery = ''; // Internally: Set to last built query (not necessarily executed...) 00139 var $store_lastBuiltQuery = FALSE; // Set "TRUE" if you want the last built query to be stored in $debug_lastBuiltQuery independent of $this->debugOutput 00140 00141 // Default link identifier: 00142 var $link; 00143 00144 00145 00146 00147 /************************************ 00148 * 00149 * Query execution 00150 * 00151 * These functions are the RECOMMENDED DBAL functions for use in your applications 00152 * Using these functions will allow the DBAL to use alternative ways of accessing data (contrary to if a query is returned!) 00153 * They compile a query AND execute it immediately and then return the result 00154 * This principle heightens our ability to create various forms of DBAL of the functions. 00155 * Generally: We want to return a result pointer/object, never queries. 00156 * Also, having the table name together with the actual query execution allows us to direct the request to other databases. 00157 * 00158 **************************************/ 00159 00169 function exec_INSERTquery($table,$fields_values) { 00170 $res = mysql_query($this->INSERTquery($table,$fields_values), $this->link); 00171 if ($this->debugOutput) $this->debug('exec_INSERTquery'); 00172 return $res; 00173 } 00174 00185 function exec_UPDATEquery($table,$where,$fields_values) { 00186 $res = mysql_query($this->UPDATEquery($table,$where,$fields_values), $this->link); 00187 if ($this->debugOutput) $this->debug('exec_UPDATEquery'); 00188 return $res; 00189 } 00190 00199 function exec_DELETEquery($table,$where) { 00200 $res = mysql_query($this->DELETEquery($table,$where), $this->link); 00201 if ($this->debugOutput) $this->debug('exec_DELETEquery'); 00202 return $res; 00203 } 00204 00218 function exec_SELECTquery($select_fields,$from_table,$where_clause,$groupBy='',$orderBy='',$limit='') { 00219 $res = mysql_query($this->SELECTquery($select_fields,$from_table,$where_clause,$groupBy,$orderBy,$limit), $this->link); 00220 if ($this->debugOutput) $this->debug('exec_SELECTquery'); 00221 return $res; 00222 } 00223 00243 function exec_SELECT_mm_query($select,$local_table,$mm_table,$foreign_table,$whereClause='',$groupBy='',$orderBy='',$limit='') { 00244 $mmWhere = $local_table ? $local_table.'.uid='.$mm_table.'.uid_local' : ''; 00245 $mmWhere.= ($local_table AND $foreign_table) ? ' AND ' : ''; 00246 $mmWhere.= $foreign_table ? $foreign_table.'.uid='.$mm_table.'.uid_foreign' : ''; 00247 return $GLOBALS['TYPO3_DB']->exec_SELECTquery( 00248 $select, 00249 ($local_table ? $local_table.',' : '').$mm_table.($foreign_table ? ','.$foreign_table : ''), 00250 $mmWhere.' '.$whereClause, // whereClauseMightContainGroupOrderBy 00251 $groupBy, 00252 $orderBy, 00253 $limit 00254 ); 00255 } 00256 00266 function exec_SELECT_queryArray($queryParts) { 00267 return $this->exec_SELECTquery( 00268 $queryParts['SELECT'], 00269 $queryParts['FROM'], 00270 $queryParts['WHERE'], 00271 $queryParts['GROUPBY'], 00272 $queryParts['ORDERBY'], 00273 $queryParts['LIMIT'] 00274 ); 00275 } 00276 00289 function exec_SELECTgetRows($select_fields,$from_table,$where_clause,$groupBy='',$orderBy='',$limit='',$uidIndexField='') { 00290 $res = $this->exec_SELECTquery($select_fields,$from_table,$where_clause,$groupBy,$orderBy,$limit); 00291 if ($this->debugOutput) $this->debug('exec_SELECTquery'); 00292 00293 unset($output); 00294 if (!$this->sql_error()) { 00295 $output = array(); 00296 00297 if ($uidIndexField) { 00298 while($tempRow = $this->sql_fetch_assoc($res)) { 00299 $output[$tempRow[$uidIndexField]] = $tempRow; 00300 } 00301 } else { 00302 while($output[] = $this->sql_fetch_assoc($res)); 00303 array_pop($output); 00304 } 00305 } 00306 return $output; 00307 } 00308 00309 00310 00311 00312 00313 00314 00315 00316 00317 00318 00319 /************************************** 00320 * 00321 * Query building 00322 * 00323 **************************************/ 00324 00334 function INSERTquery($table,$fields_values) { 00335 00336 // Table and fieldnames should be "SQL-injection-safe" when supplied to this function (contrary to values in the arrays which may be insecure). 00337 if (is_array($fields_values) && count($fields_values)) { 00338 00339 // Add slashes old-school: 00340 foreach($fields_values as $k => $v) { 00341 $fields_values[$k] = $this->fullQuoteStr($fields_values[$k], $table); 00342 } 00343 00344 // Build query: 00345 $query = 'INSERT INTO '.$table.' 00346 ( 00347 '.implode(', 00348 ',array_keys($fields_values)).' 00349 ) VALUES ( 00350 '.implode(', 00351 ',$fields_values).' 00352 )'; 00353 00354 // Return query: 00355 if ($this->debugOutput || $this->store_lastBuiltQuery) $this->debug_lastBuiltQuery = $query; 00356 return $query; 00357 } 00358 } 00359 00370 function UPDATEquery($table,$where,$fields_values) { 00371 00372 // Table and fieldnames should be "SQL-injection-safe" when supplied to this function (contrary to values in the arrays which may be insecure). 00373 if (is_string($where)) { 00374 if (is_array($fields_values) && count($fields_values)) { 00375 00376 // Add slashes old-school: 00377 $nArr = array(); 00378 foreach($fields_values as $k => $v) { 00379 $nArr[] = $k.'='.$this->fullQuoteStr($v, $table); 00380 } 00381 00382 // Build query: 00383 $query = 'UPDATE '.$table.' 00384 SET 00385 '.implode(', 00386 ',$nArr). 00387 (strlen($where)>0 ? ' 00388 WHERE 00389 '.$where : ''); 00390 00391 // Return query: 00392 if ($this->debugOutput || $this->store_lastBuiltQuery) $this->debug_lastBuiltQuery = $query; 00393 return $query; 00394 } 00395 } else { 00396 die('<strong>TYPO3 Fatal Error:</strong> "Where" clause argument for UPDATE query was not a string in $this->UPDATEquery() !'); 00397 } 00398 } 00399 00409 function DELETEquery($table,$where) { 00410 if (is_string($where)) { 00411 00412 // Table and fieldnames should be "SQL-injection-safe" when supplied to this function 00413 $query = 'DELETE FROM '.$table. 00414 (strlen($where)>0 ? ' 00415 WHERE 00416 '.$where : ''); 00417 00418 if ($this->debugOutput || $this->store_lastBuiltQuery) $this->debug_lastBuiltQuery = $query; 00419 return $query; 00420 } else { 00421 die('<strong>TYPO3 Fatal Error:</strong> "Where" clause argument for DELETE query was not a string in $this->DELETEquery() !'); 00422 } 00423 } 00424 00438 function SELECTquery($select_fields,$from_table,$where_clause,$groupBy='',$orderBy='',$limit='') { 00439 00440 // Table and fieldnames should be "SQL-injection-safe" when supplied to this function 00441 // Build basic query: 00442 $query = 'SELECT '.$select_fields.' 00443 FROM '.$from_table. 00444 (strlen($where_clause)>0 ? ' 00445 WHERE 00446 '.$where_clause : ''); 00447 00448 // Group by: 00449 if (strlen($groupBy)>0) { 00450 $query.= ' 00451 GROUP BY '.$groupBy; 00452 } 00453 // Order by: 00454 if (strlen($orderBy)>0) { 00455 $query.= ' 00456 ORDER BY '.$orderBy; 00457 } 00458 // Group by: 00459 if (strlen($limit)>0) { 00460 $query.= ' 00461 LIMIT '.$limit; 00462 } 00463 00464 // Return query: 00465 if ($this->debugOutput || $this->store_lastBuiltQuery) $this->debug_lastBuiltQuery = $query; 00466 return $query; 00467 } 00468 00479 function listQuery($field, $value, $table) { 00480 $command = $this->quoteStr($value, $table); 00481 $where = '('.$field.' LIKE \'%,'.$command.',%\' OR '.$field.' LIKE \''.$command.',%\' OR '.$field.' LIKE \'%,'.$command.'\' OR '.$field.'=\''.$command.'\')'; 00482 return $where; 00483 } 00484 00493 function searchQuery($searchWords,$fields,$table) { 00494 $queryParts = array(); 00495 00496 foreach($searchWords as $sw) { 00497 $like=' LIKE \'%'.$this->quoteStr($sw, $table).'%\''; 00498 $queryParts[] = $table.'.'.implode($like.' OR '.$table.'.',$fields).$like; 00499 } 00500 $query = '('.implode(') AND (',$queryParts).')'; 00501 return $query ; 00502 } 00503 00504 00505 00506 00507 00508 00509 00510 00511 00512 00513 00514 00515 00516 00517 00518 00519 /************************************** 00520 * 00521 * Various helper functions 00522 * 00523 * Functions recommended to be used for 00524 * - escaping values, 00525 * - cleaning lists of values, 00526 * - stripping of excess ORDER BY/GROUP BY keywords 00527 * 00528 **************************************/ 00529 00539 function fullQuoteStr($str, $table) { 00540 return '\''.addslashes($str).'\''; 00541 } 00542 00555 function quoteStr($str, $table) { 00556 return addslashes($str); 00557 } 00558 00568 function cleanIntArray($arr) { 00569 foreach($arr as $k => $v) { 00570 $arr[$k] = intval($arr[$k]); 00571 } 00572 return $arr; 00573 } 00574 00584 function cleanIntList($list) { 00585 return implode(',',t3lib_div::intExplode(',',$list)); 00586 } 00587 00598 function stripOrderBy($str) { 00599 return preg_replace('/^ORDER[[:space:]]+BY[[:space:]]+/i','',trim($str)); 00600 } 00601 00612 function stripGroupBy($str) { 00613 return preg_replace('/^GROUP[[:space:]]+BY[[:space:]]+/i','',trim($str)); 00614 } 00615 00624 function splitGroupOrderLimit($str) { 00625 $str = ' '.$str; // Prepending a space to make sure "[[:space:]]+" will find a space there for the first element. 00626 // Init output array: 00627 $wgolParts = array( 00628 'WHERE' => '', 00629 'GROUPBY' => '', 00630 'ORDERBY' => '', 00631 'LIMIT' => '' 00632 ); 00633 00634 // Find LIMIT: 00635 if (preg_match('/^(.*)[[:space:]]+LIMIT[[:space:]]+([[:alnum:][:space:],._]+)$/i',$str,$reg)) { 00636 $wgolParts['LIMIT'] = trim($reg[2]); 00637 $str = $reg[1]; 00638 } 00639 00640 // Find ORDER BY: 00641 if (preg_match('/^(.*)[[:space:]]+ORDER[[:space:]]+BY[[:space:]]+([[:alnum:][:space:],._]+)$/i',$str,$reg)) { 00642 $wgolParts['ORDERBY'] = trim($reg[2]); 00643 $str = $reg[1]; 00644 } 00645 00646 // Find GROUP BY: 00647 if (preg_match('/^(.*)[[:space:]]+GROUP[[:space:]]+BY[[:space:]]+([[:alnum:][:space:],._]+)$/i',$str,$reg)) { 00648 $wgolParts['GROUPBY'] = trim($reg[2]); 00649 $str = $reg[1]; 00650 } 00651 00652 // Rest is assumed to be "WHERE" clause: 00653 $wgolParts['WHERE'] = $str; 00654 00655 return $wgolParts; 00656 } 00657 00658 00659 00660 00661 00662 00663 00664 00665 00666 00667 00668 00669 00670 00671 00672 /************************************** 00673 * 00674 * MySQL wrapper functions 00675 * (For use in your applications) 00676 * 00677 **************************************/ 00678 00689 function sql($db,$query) { 00690 $res = mysql_query($query, $this->link); 00691 if ($this->debugOutput) $this->debug('sql'); 00692 return $res; 00693 } 00694 00703 function sql_query($query) { 00704 $res = mysql_query($query, $this->link); 00705 if ($this->debugOutput) $this->debug('sql_query'); 00706 return $res; 00707 } 00708 00716 function sql_error() { 00717 return mysql_error($this->link); 00718 } 00719 00728 function sql_num_rows($res) { 00729 return mysql_num_rows($res); 00730 } 00731 00740 function sql_fetch_assoc($res) { 00741 return mysql_fetch_assoc($res); 00742 } 00743 00753 function sql_fetch_row($res) { 00754 return mysql_fetch_row($res); 00755 } 00756 00765 function sql_free_result($res) { 00766 return mysql_free_result($res); 00767 } 00768 00776 function sql_insert_id() { 00777 return mysql_insert_id($this->link); 00778 } 00779 00787 function sql_affected_rows() { 00788 return mysql_affected_rows($this->link); 00789 } 00790 00800 function sql_data_seek($res,$seek) { 00801 return mysql_data_seek($res,$seek); 00802 } 00803 00813 function sql_field_type($res,$pointer) { 00814 return mysql_field_type($res,$pointer); 00815 } 00816 00827 function sql_pconnect($TYPO3_db_host, $TYPO3_db_username, $TYPO3_db_password) { 00828 if ($GLOBALS['TYPO3_CONF_VARS']['SYS']['no_pconnect']) { 00829 $this->link = mysql_connect($TYPO3_db_host, $TYPO3_db_username, $TYPO3_db_password); 00830 } else { 00831 $this->link = mysql_pconnect($TYPO3_db_host, $TYPO3_db_username, $TYPO3_db_password); 00832 } 00833 return $this->link; 00834 } 00835 00844 function sql_select_db($TYPO3_db) { 00845 return mysql_select_db($TYPO3_db, $this->link); 00846 } 00847 00848 00849 00850 00851 00852 00853 00854 00855 00856 00857 /************************************** 00858 * 00859 * SQL admin functions 00860 * (For use in the Install Tool and Extension Manager) 00861 * 00862 **************************************/ 00863 00872 function admin_get_dbs() { 00873 $dbArr = array(); 00874 $db_list = mysql_list_dbs($this->link); 00875 while ($row = mysql_fetch_object($db_list)) { 00876 if ($this->sql_select_db($row->Database)) { 00877 $dbArr[] = $row->Database; 00878 } 00879 } 00880 return $dbArr; 00881 } 00882 00890 function admin_get_tables() { 00891 $whichTables = array(); 00892 $tables_result = mysql_list_tables(TYPO3_db, $this->link); 00893 if (!mysql_error()) { 00894 while ($theTable = mysql_fetch_assoc($tables_result)) { 00895 $whichTables[current($theTable)] = current($theTable); 00896 } 00897 } 00898 return $whichTables; 00899 } 00900 00909 function admin_get_fields($tableName) { 00910 $output = array(); 00911 00912 $columns_res = mysql_query('SHOW columns FROM '.$tableName, $this->link); 00913 while($fieldRow = mysql_fetch_assoc($columns_res)) { 00914 $output[$fieldRow["Field"]] = $fieldRow; 00915 } 00916 00917 return $output; 00918 } 00919 00927 function admin_get_keys($tableName) { 00928 $output = array(); 00929 00930 $keyRes = mysql_query('SHOW keys FROM '.$tableName, $this->link); 00931 while($keyRow = mysql_fetch_assoc($keyRes)) { 00932 $output[] = $keyRow; 00933 } 00934 00935 return $output; 00936 } 00937 00945 function admin_query($query) { 00946 $res = mysql_query($query, $this->link); 00947 if ($this->debugOutput) $this->debug('admin_query'); 00948 return $res; 00949 } 00950 00951 00952 00953 00954 00955 00956 00957 00958 00959 00960 /****************************** 00961 * 00962 * Debugging 00963 * 00964 ******************************/ 00965 00972 function debug($func) { 00973 00974 $error = $this->sql_error(); 00975 if ($error) { 00976 echo t3lib_div::view_array(array( 00977 'caller' => 't3lib_DB::'.$func, 00978 'ERROR' => $error, 00979 'lastBuiltQuery' => $this->debug_lastBuiltQuery, 00980 'debug_backtrace' => function_exists('debug_backtrace') ? next(debug_backtrace()) : 'N/A' 00981 )); 00982 } 00983 } 00984 } 00985 00986 00987 if (defined('TYPO3_MODE') && $TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_db.php']) { 00988 include_once($TYPO3_CONF_VARS[TYPO3_MODE]['XCLASS']['t3lib/class.t3lib_db.php']); 00989 } 00990 ?>