Completed
Pull Request — master (#2282)
by ྅༻ Ǭɀħ
01:44
created

includes/ezSQL/ez_sql_mysqli.php (10 issues)

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
3
	/**********************************************************************
4
	*  Author: Juergen Bouch� ([email protected])
5
	*  Web...: http://www.juergenbouche.de
6
	*  Name..: ezSQL_mysqli
7
	*  Desc..: mySQLi component (part of ezSQL database abstraction library)
8
	*
9
	*/
10
11
	/**********************************************************************
12
	*  ezSQL error strings - mySQLi
13
	*/
14
    
15
    global $ezsql_mysqli_str;
16
17
	$ezsql_mysqli_str = array
18
	(
19
		1 => 'Require $dbuser and $dbpassword to connect to a database server',
20
		2 => 'Error establishing mySQLi database connection. Correct user/password? Correct hostname? Database server running?',
21
		3 => 'Require $dbname to select a database',
22
		4 => 'mySQLi database connection is not active',
23
		5 => 'Unexpected error while trying to select database'
24
	);
25
26
	/**********************************************************************
27
	*  ezSQL Database specific class - mySQLi
28
	*/
29
30
	if ( ! function_exists ('mysqli_connect') ) die('<b>Fatal Error:</b> ezSQL_mysql requires mySQLi Lib to be compiled and or linked in to the PHP engine');
31
	if ( ! class_exists ('ezSQLcore') ) die('<b>Fatal Error:</b> ezSQL_mysql requires ezSQLcore (ez_sql_core.php) to be included/loaded before it can be used');
32
33
	class ezSQL_mysqli extends ezSQLcore
34
	{
35
36
		var $dbuser = false;
37
		var $dbpassword = false;
38
		var $dbname = false;
39
		var $dbhost = false;
40
		var $dbport = false;
41
		var $encoding = false;
42
		var $rows_affected = false;
43
44
		/**********************************************************************
45
		*  Constructor - allow the user to perform a qucik connect at the
46
		*  same time as initialising the ezSQL_mysqli class
47
		*/
48
49 View Code Duplication
		function __construct($dbuser='', $dbpassword='', $dbname='', $dbhost='localhost', $encoding='')
50
		{
51
			$this->dbuser = $dbuser;
52
			$this->dbpassword = $dbpassword;
53
			$this->dbname = $dbname;
54
			list( $this->dbhost, $this->dbport ) = $this->get_host_port( $dbhost, 3306 );
55
			$this->encoding = $encoding;
56
		}
57
58
		/**********************************************************************
59
		*  Short hand way to connect to mySQL database server
60
		*  and select a mySQL database at the same time
61
		*/
62
63 View Code Duplication
		function quick_connect($dbuser='', $dbpassword='', $dbname='', $dbhost='localhost', $dbport='3306', $encoding='')
64
		{
65
			$return_val = false;
66
			if ( ! $this->connect($dbuser, $dbpassword, $dbhost, $dbport) ) ;
67
			else if ( ! $this->select($dbname,$encoding) ) ;
68
			else $return_val = true;
69
			return $return_val;
70
		}
71
72
		/**********************************************************************
73
		*  Try to connect to mySQL database server
74
		*/
75
76
		function connect($dbuser='', $dbpassword='', $dbhost='localhost', $dbport=false)
77
		{
78
			global $ezsql_mysqli_str; $return_val = false;
79
			
80
			// Keep track of how long the DB takes to connect
81
			$this->timer_start('db_connect_time');
82
			
83
			// If port not specified (new connection issued), get it
84
			if( ! $dbport ) {
85
				list( $dbhost, $dbport ) = $this->get_host_port( $dbhost, 3306 );
86
			}
87
			
88
			// Must have a user and a password
89
			if ( ! $dbuser )
90
			{
91
				$this->register_error($ezsql_mysqli_str[1].' in '.__FILE__.' on line '.__LINE__);
92
				$this->show_errors ? trigger_error($ezsql_mysqli_str[1],E_USER_WARNING) : null;
93
			}
94
			// Try to establish the server database handle
95
			else
96
			{
97
				$this->dbh = new mysqli($dbhost,$dbuser,$dbpassword, '', $dbport);
0 ignored issues
show
The property dbh does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
98
                // Check for connection problem
99
                if( $this->dbh->connect_errno )
100
                {
101
                    $this->register_error($ezsql_mysqli_str[2].' in '.__FILE__.' on line '.__LINE__);
102
                    $this->show_errors ? trigger_error($ezsql_mysqli_str[2],E_USER_WARNING) : null;
103
                }
104 View Code Duplication
                else
105
                {
106
                    $this->dbuser = $dbuser;
107
                    $this->dbpassword = $dbpassword;
108
                    $this->dbhost = $dbhost;
109
                    $this->dbport = $dbport;
110
                    $return_val = true;
111
                }
112
			}
113
114
			return $return_val;
115
		}
116
117
		/**********************************************************************
118
		*  Try to select a mySQL database
119
		*/
120
121
		function select($dbname='', $encoding='')
122
		{
123
			global $ezsql_mysqli_str; $return_val = false;
124
125
			// Must have a database name
126
			if ( ! $dbname )
127
			{
128
				$this->register_error($ezsql_mysqli_str[3].' in '.__FILE__.' on line '.__LINE__);
129
				$this->show_errors ? trigger_error($ezsql_mysqli_str[3],E_USER_WARNING) : null;
130
			}
131
132
			// Must have an active database connection
133
			else if ( ! $this->dbh )
134
			{
135
				$this->register_error($ezsql_mysqli_str[4].' in '.__FILE__.' on line '.__LINE__);
136
				$this->show_errors ? trigger_error($ezsql_mysqli_str[4],E_USER_WARNING) : null;
137
			}
138
139
			// Try to connect to the database
140
			else if ( !@$this->dbh->select_db($dbname) )
141
			{
142
				// Try to get error supplied by mysql if not use our own
143
				if ( !$str = @$this->dbh->error)
144
					  $str = $ezsql_mysqli_str[5];
145
146
				$this->register_error($str.' in '.__FILE__.' on line '.__LINE__);
147
				$this->show_errors ? trigger_error($str,E_USER_WARNING) : null;
148
			}
149
			else
150
			{
151
				$this->dbname = $dbname;
152
				if($encoding!='')
153
				{
154
					$encoding = strtolower(str_replace("-","",$encoding));
155
					$charsets = array();
156
					$result = $this->dbh->query("SHOW CHARACTER SET");
157
					while($row = $result->fetch_array(MYSQLI_ASSOC))
158
					{
159
						$charsets[] = $row["Charset"];
160
					}
161
					if(in_array($encoding,$charsets)){
162
						$this->dbh->query("SET NAMES '".$encoding."'");						
163
					}
164
				}
165
				
166
				$return_val = true;
167
			}
168
169
			return $return_val;
170
		}
171
172
		/**********************************************************************
173
		*  Format a mySQL string correctly for safe mySQL insert
174
		*  (no mater if magic quotes are on or not)
175
		*/
176
177
		function escape($str)
178
		{
179
			// If there is no existing database connection then try to connect
180
			if ( ! isset($this->dbh) || ! $this->dbh )
181
			{
182
				$this->connect($this->dbuser, $this->dbpassword, $this->dbhost, $this->dbport);
183
				$this->select($this->dbname, $this->encoding);
184
			}
185
186
			return $this->dbh->escape_string(stripslashes($str));
187
		}
188
189
		/**********************************************************************
190
		*  Return mySQL specific system date syntax
191
		*  i.e. Oracle: SYSDATE Mysql: NOW()
192
		*/
193
194
		function sysdate()
195
		{
196
			return 'NOW()';
197
		}
198
199
		/**********************************************************************
200
		*  Perform mySQL query and try to determine result value
201
		*/
202
203
		function query($query)
204
		{
205
206
			// This keeps the connection alive for very long running scripts
207 View Code Duplication
			if ( $this->num_queries >= 500 )
208
			{
209
				$this->disconnect();
210
				$this->quick_connect($this->dbuser,$this->dbpassword,$this->dbname,$this->dbhost,$this->dbport,$this->encoding);
211
			}
212
213
			// Initialise return
214
			$return_val = 0;
0 ignored issues
show
$return_val is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
215
216
			// Flush cached values..
217
			$this->flush();
218
219
			// For reg expressions
220
			$query = trim($query);
221
222
			// Log how the function was called
223
			$this->func_call = "\$db->query(\"$query\")";
0 ignored issues
show
The property func_call does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
224
225
			// Keep track of the last query for debug..
226
			$this->last_query = $query;
227
228
			// Count how many queries there have been
229
			$this->num_queries++;
230
			
231
			// Start timer
232
			$this->timer_start($this->num_queries);
233
234
			// Use core file cache function
235 View Code Duplication
			if ( $cache = $this->get_cache($query) )
236
			{
237
				// Keep tack of how long all queries have taken
238
				$this->timer_update_global($this->num_queries);
239
240
				// Trace all queries
241
				if ( $this->use_trace_log )
242
				{
243
					$this->trace_log[] = $this->debug(false);
244
				}
245
				
246
				return $cache;
247
			}
248
            
249
250
			// If there is no existing database connection then try to connect
251 View Code Duplication
			if ( ! isset($this->dbh) || ! $this->dbh )
252
			{
253
				$this->connect($this->dbuser, $this->dbpassword, $this->dbhost, $this->dbport);
254
				$this->select($this->dbname,$this->encoding);
255
                if ( ! isset($this->dbh) || $this->dbh->connect_errno )
256
                    return false;
257
			}
258
259
			// Perform the query via std mysql_query function..
260
			$this->result = @$this->dbh->query($query);
0 ignored issues
show
The property result does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
261
262
			// If there is an error then take note of it..
263 View Code Duplication
			if ( $str = @$this->dbh->error )
264
			{
265
				$is_insert = true;
0 ignored issues
show
$is_insert is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
266
				$this->register_error($str);
267
				$this->show_errors ? trigger_error($str,E_USER_WARNING) : null;
268
				return false;
269
			}
270
271
			// Query was an insert, delete, update, replace
272
			$is_insert = false;
273
			
274
			//if ( preg_match("/^(insert|delete|update|replace|truncate|drop|create|alter)\s+/i",$query) )
275
			if ( preg_match("/^(insert|delete|update|replace|truncate|drop|create|alter|begin|commit|rollback|set)/i",$query) )
276
			{
277
				$this->rows_affected = @$this->dbh->affected_rows;
278
279
				// Take note of the insert_id
280
				if ( preg_match("/^(insert|replace)\s+/i",$query) )
281
				{
282
					$this->insert_id = @$this->dbh->insert_id;
0 ignored issues
show
The property insert_id does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
283
				}
284
285
				// Return number fo rows affected
286
				$return_val = $this->rows_affected;
287
			}
288
			// Query was a select
289
			else
290
			{
291
292
				// Take note of column info
293
				$i=0;
294
				while ($i < @$this->result->field_count)
295
				{
296
					$this->col_info[$i] = @$this->result->fetch_field();
297
					$i++;
298
				}
299
300
				// Store Query Results
301
				$num_rows=0;
302
				while ( $row = @$this->result->fetch_object() )
303
				{
304
					// Store relults as an objects within main array
305
					$this->last_result[$num_rows] = $row;
0 ignored issues
show
The property last_result does not seem to exist. Did you mean result?

An attempt at access to an undefined property has been detected. This may either be a typographical error or the property has been renamed but there are still references to its old name.

If you really want to allow access to undefined properties, you can define magic methods to allow access. See the php core documentation on Overloading.

Loading history...
306
					$num_rows++;
307
				}
308
309
				@$this->result->free_result();
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
310
311
				// Log number of rows the query returned
312
				$this->num_rows = $num_rows;
0 ignored issues
show
The property num_rows does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
313
314
				// Return number of rows selected
315
				$return_val = $this->num_rows;
316
			}
317
318
			// disk caching of queries
319
			$this->store_cache($query,$is_insert);
320
321
			// If debug ALL queries
322
			$this->trace || $this->debug_all ? $this->debug() : null ;
323
324
			// Keep tack of how long all queries have taken
325
			$this->timer_update_global($this->num_queries);
326
327
			// Trace all queries
328
			if ( $this->use_trace_log )
329
			{
330
				$this->trace_log[] = $this->debug(false);
331
			}
332
333
			return $return_val;
334
335
		}
336
		
337
		/**********************************************************************
338
		*  Close the active mySQLi connection
339
		*/
340
341
		function disconnect()
342
		{
343
			@$this->dbh->close();
0 ignored issues
show
Security Best Practice introduced by
It seems like you do not handle an error condition here. This can introduce security issues, and is generally not recommended.

If you suppress an error, we recommend checking for the error condition explicitly:

// For example instead of
@mkdir($dir);

// Better use
if (@mkdir($dir) === false) {
    throw new \RuntimeException('The directory '.$dir.' could not be created.');
}
Loading history...
344
		}
345
346
	}
347