]> git.mxchange.org Git - friendica.git/blob - include/dba.php
Merge pull request #891 from tobiasd/check_http_in_homepage
[friendica.git] / include / dba.php
1 <?php
2
3 require_once('include/datetime.php');
4
5 /**
6  *
7  * MySQL database class
8  *
9  * For debugging, insert 'dbg(1);' anywhere in the program flow.
10  * dbg(0); will turn it off. Logging is performed at LOGGER_DATA level.
11  * When logging, all binary info is converted to text and html entities are escaped so that 
12  * the debugging stream is safe to view within both terminals and web pages.
13  *
14  */
15  
16 if(! class_exists('dba')) { 
17 class dba {
18
19         private $debug = 0;
20         private $db;
21         public  $mysqli = true;
22         public  $connected = false;
23         public  $error = false;
24
25         function __construct($server,$user,$pass,$db,$install = false) {
26                 global $a;
27
28                 $stamp1 = microtime(true);
29
30                 $server = trim($server);
31                 $user = trim($user);
32                 $pass = trim($pass);
33                 $db = trim($db);
34
35                 if (!(strlen($server) && strlen($user))){
36                         $this->connected = false;
37                         $this->db = null;
38                         return;
39                 }
40
41                 if($install) {
42                         if(strlen($server) && ($server !== 'localhost') && ($server !== '127.0.0.1')) {
43                                 if(! dns_get_record($server, DNS_A + DNS_CNAME + DNS_PTR)) {
44                                         $this->error = sprintf( t('Cannot locate DNS info for database server \'%s\''), $server);
45                                         $this->connected = false;
46                                         $this->db = null;
47                                         return;
48                                 }
49                         }
50                 }
51
52                 if(class_exists('mysqli')) {
53                         $this->db = @new mysqli($server,$user,$pass,$db);
54                         if(! mysqli_connect_errno()) {
55                                 $this->connected = true;
56                         }
57                 }
58                 else {
59                         $this->mysqli = false;
60                         $this->db = mysql_connect($server,$user,$pass);
61                         if($this->db && mysql_select_db($db,$this->db)) {
62                                 $this->connected = true;
63                         }
64                 }
65                 if(! $this->connected) {
66                         $this->db = null;
67                         if(! $install)
68                                 system_unavailable();
69                 }
70
71                 $a->save_timestamp($stamp1, "network");
72         }
73
74         public function getdb() {
75                 return $this->db;
76         }
77
78         public function q($sql) {
79                 global $a;
80
81                 if((! $this->db) || (! $this->connected))
82                         return false;
83
84                 $this->error = '';
85
86                 $stamp1 = microtime(true);
87
88                 if($this->mysqli)
89                         $result = @$this->db->query($sql);
90                 else
91                         $result = @mysql_query($sql,$this->db);
92
93                 $stamp2 = microtime(true);
94                 $duration = (float)($stamp2-$stamp1);
95
96                 $a->save_timestamp($stamp1, "database");
97
98                 if(x($a->config,'system') && x($a->config['system'],'db_log')) {
99                         if (($duration > $a->config["system"]["db_loglimit"])) {
100                                 $duration = round($duration, 3);
101                                 $backtrace = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
102                                 @file_put_contents($a->config["system"]["db_log"], datetime_convert()."\t".$duration."\t".
103                                                 basename($backtrace[1]["file"])."\t".
104                                                 $backtrace[1]["line"]."\t".$backtrace[2]["function"]."\t".
105                                                 substr($sql, 0, 2000)."\n", FILE_APPEND);
106                         }
107                 }
108
109                 if($this->mysqli) {
110                         if($this->db->errno)
111                                 $this->error = $this->db->error;
112                 }
113                 elseif(mysql_errno($this->db))
114                                 $this->error = mysql_error($this->db);
115
116                 if(strlen($this->error)) {
117                         logger('dba: ' . $this->error);
118                 }
119
120                 if($this->debug) {
121
122                         $mesg = '';
123
124                         if($result === false)
125                                 $mesg = 'false';
126                         elseif($result === true)
127                                 $mesg = 'true';
128                         else {
129                                 if($this->mysqli)
130                                         $mesg = $result->num_rows . ' results' . EOL;
131                         else
132                                         $mesg = mysql_num_rows($result) . ' results' . EOL;
133                         }
134
135                         $str =  'SQL = ' . printable($sql) . EOL . 'SQL returned ' . $mesg
136                                 . (($this->error) ? ' error: ' . $this->error : '')
137                                 . EOL;
138
139                         logger('dba: ' . $str );
140                 }
141
142                 /**
143                  * If dbfail.out exists, we will write any failed calls directly to it,
144                  * regardless of any logging that may or may nor be in effect.
145                  * These usually indicate SQL syntax errors that need to be resolved.
146                  */
147
148                 if($result === false) {
149                         logger('dba: ' . printable($sql) . ' returned false.' . "\n" . $this->error);
150                         if(file_exists('dbfail.out'))
151                                 file_put_contents('dbfail.out', datetime_convert() . "\n" . printable($sql) . ' returned false' . "\n" . $this->error . "\n", FILE_APPEND);
152                 }
153
154                 if(($result === true) || ($result === false))
155                         return $result;
156
157                 $r = array();
158                 if($this->mysqli) {
159                         if($result->num_rows) {
160                                 while($x = $result->fetch_array(MYSQLI_ASSOC))
161                                         $r[] = $x;
162                                 $result->free_result();
163                         }
164                 }
165                 else {
166                         if(mysql_num_rows($result)) {
167                                 while($x = mysql_fetch_array($result, MYSQL_ASSOC))
168                                         $r[] = $x;
169                                 mysql_free_result($result);
170                         }
171                 }
172
173                 //$a->save_timestamp($stamp1, "database");
174
175                 if($this->debug)
176                         logger('dba: ' . printable(print_r($r, true)));
177                 return($r);
178         }
179
180         public function dbg($dbg) {
181                 $this->debug = $dbg;
182         }
183
184         public function escape($str) {
185                 if($this->db && $this->connected) {
186                         if($this->mysqli)
187                                 return @$this->db->real_escape_string($str);
188                         else
189                                 return @mysql_real_escape_string($str,$this->db);
190                 }
191         }
192
193         function __destruct() {
194                 if ($this->db) 
195                         if($this->mysqli)
196                                 $this->db->close();
197                         else
198                                 mysql_close($this->db);
199         }
200 }}
201
202 if(! function_exists('printable')) {
203 function printable($s) {
204         $s = preg_replace("~([\x01-\x08\x0E-\x0F\x10-\x1F\x7F-\xFF])~",".", $s);
205         $s = str_replace("\x00",'.',$s);
206         if(x($_SERVER,'SERVER_NAME'))
207                 $s = escape_tags($s);
208         return $s;
209 }}
210
211 // Procedural functions
212 if(! function_exists('dbg')) { 
213 function dbg($state) {
214         global $db;
215         if($db)
216         $db->dbg($state);
217 }}
218
219 if(! function_exists('dbesc')) { 
220 function dbesc($str) {
221         global $db;
222         if($db && $db->connected)
223                 return($db->escape($str));
224         else
225                 return(str_replace("'","\\'",$str));
226 }}
227
228
229
230 // Function: q($sql,$args);
231 // Description: execute SQL query with printf style args.
232 // Example: $r = q("SELECT * FROM `%s` WHERE `uid` = %d",
233 //                   'user', 1);
234
235 if(! function_exists('q')) { 
236 function q($sql) {
237
238         global $db;
239         $args = func_get_args();
240         unset($args[0]);
241
242         if($db && $db->connected) {
243                 $stmt = @vsprintf($sql,$args); // Disabled warnings
244                 //logger("dba: q: $stmt", LOGGER_ALL);
245                 if($stmt === false)
246                         logger('dba: vsprintf error: ' . print_r(debug_backtrace(),true), LOGGER_DEBUG);
247                 return $db->q($stmt);
248         }
249
250         /**
251          *
252          * This will happen occasionally trying to store the 
253          * session data after abnormal program termination 
254          *
255          */
256         logger('dba: no database: ' . print_r($args,true));
257         return false; 
258
259 }}
260
261 /**
262  *
263  * Raw db query, no arguments
264  *
265  */
266
267 if(! function_exists('dbq')) { 
268 function dbq($sql) {
269
270         global $db;
271         if($db && $db->connected)
272                 $ret = $db->q($sql);
273         else
274                 $ret = false;
275         return $ret;
276 }}
277
278
279 // Caller is responsible for ensuring that any integer arguments to 
280 // dbesc_array are actually integers and not malformed strings containing
281 // SQL injection vectors. All integer array elements should be specifically 
282 // cast to int to avoid trouble. 
283
284
285 if(! function_exists('dbesc_array_cb')) {
286 function dbesc_array_cb(&$item, $key) {
287         if(is_string($item))
288                 $item = dbesc($item);
289 }}
290
291
292 if(! function_exists('dbesc_array')) {
293 function dbesc_array(&$arr) {
294         if(is_array($arr) && count($arr)) {
295                 array_walk($arr,'dbesc_array_cb');
296         }
297 }}
298
299
300 function dba_timer() {
301         return microtime(true);
302 }
303