ezSQLcore   F
last analyzed

Complexity

Total Complexity 90

Size/Duplication

Total Lines 608
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 0

Importance

Changes 0
Metric Value
dl 0
loc 608
c 0
b 0
f 0
wmc 90
lcom 1
cbo 0
rs 1.992

23 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A get_host_port() 0 9 2
A register_error() 0 11 1
A show_errors() 0 4 1
A hide_errors() 0 4 1
A flush() 0 8 1
A get_var() 0 21 5
B get_row() 0 34 9
A get_col() 0 20 3
B get_results() 0 42 8
A get_col_info() 0 22 4
B store_cache() 0 30 9
B get_cache() 0 33 8
B vardump() 0 38 6
A dumpvar() 0 4 1
C debug() 0 106 12
A donation() 0 4 1
A timer_get_cur() 0 5 1
A timer_start() 0 4 1
A timer_elapsed() 0 4 1
A timer_update_global() 0 12 2
B get_set() 0 27 9
A count() 0 8 3

How to fix   Complexity   

Complex Class

Complex classes like ezSQLcore often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use ezSQLcore, and based on these observations, apply Extract Interface, too.

1
<?php
2
namespace Mmanager\Extensions\Database;
3
	/**********************************************************************
4
	*  Author: Justin Vincent ([email protected])
5
	*  Web...: http://justinvincent.com
6
	*  Name..: ezSQL
7
	*  Desc..: ezSQL Core module - database abstraction library to make
8
	*          it very easy to deal with databases. ezSQLcore can not be used by
9
	*          itself (it is designed for use by database specific modules).
10
	*
11
	*/
12
13
	/**********************************************************************
14
	*  ezSQL Constants
15
	*/
16
17
	defined('EZSQL_VERSION') or define('EZSQL_VERSION', '2.17');
18
	defined('OBJECT') or define('OBJECT', 'OBJECT');
19
	defined('ARRAY_A') or define('ARRAY_A', 'ARRAY_A');
20
	defined('ARRAY_N') or define('ARRAY_N', 'ARRAY_N');
21
22
	/**********************************************************************
23
	*  Core class containg common functions to manipulate query result
24
	*  sets once returned
25
	*/
26
27
	class ezSQLcore
28
	{
29
30
		var $trace            = false; // same as $debug_all
31
		var $debug_all        = false; // same as $trace
32
		var $debug_called     = false;
33
		var $vardump_called   = false;
34
		var $show_errors      = true;
35
		var $num_queries      = 0;
36
		var $conn_queries     = 0;
37
		var $last_query       = null;
38
		var $last_error       = null;
39
		var $col_info         = null;
40
		var $captured_errors  = array();
41
		var $cache_dir        = false;
42
		var $cache_queries    = false;
43
		var $cache_inserts    = false;
44
		var $use_disk_cache   = false;
45
		var $cache_timeout    = 24; // hours
46
		var $timers           = array();
47
		var $total_query_time = 0;
48
		var $db_connect_time  = 0;
49
		var $trace_log        = array();
50
		var $use_trace_log    = false;
51
		var $sql_log_file     = false;
52
		var $do_profile       = false;
53
		var $profile_times    = array();
54
55
		// == TJH == default now needed for echo of debug function
56
		var $debug_echo_is_on = true;
57
58
		/**********************************************************************
59
		*  Constructor
60
		*/
61
62
		function __construct()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
63
		{
64
		}
65
66
		/**********************************************************************
67
		*  Get host and port from an "host:port" notation.
68
		*  Returns array of host and port. If port is omitted, returns $default
69
		*/
70
71
		function get_host_port($host, $default = false)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
72
		{
73
			$port = $default;
74
			if (false !== strpos($host, ':')) {
75
				list($host, $port) = explode(':', $host);
76
				$port = (int) $port;
77
			}
78
			return array($host, $port);
79
		}
80
81
		/**********************************************************************
82
		*  Print SQL/DB error - over-ridden by specific DB class
83
		*/
84
85
		function register_error($err_str)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
86
		{
87
			// Keep track of last error
88
			$this->last_error = $err_str;
89
90
			// Capture all errors to an error array no matter what happens
91
			$this->captured_errors[] = array(
92
				'error_str' => $err_str,
93
				'query'     => $this->last_query
94
			);
95
		}
96
97
		/**********************************************************************
98
		*  Turn error handling on or off..
99
		*/
100
101
		function show_errors()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
102
		{
103
			$this->show_errors = true;
104
		}
105
106
		function hide_errors()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
107
		{
108
			$this->show_errors = false;
109
		}
110
111
		/**********************************************************************
112
		*  Kill cached query results
113
		*/
114
115
		function flush()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
116
		{
117
			// Get rid of these
118
			$this->last_result = null;
0 ignored issues
show
Bug introduced by
The property last_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...
119
			$this->col_info = null;
120
			$this->last_query = null;
121
			$this->from_disk_cache = false;
0 ignored issues
show
Bug introduced by
The property from_disk_cache 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...
122
		}
123
124
		/**********************************************************************
125
		*  Get one variable from the DB - see docs for more detail
126
		*/
127
128
		function get_var($query = null, $x = 0, $y = 0)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
129
		{
130
131
			// Log how the function was called
132
			$this->func_call = "\$db->get_var(\"$query\",$x,$y)";
0 ignored issues
show
Bug introduced by
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...
133
134
			// If there is a query then perform it if not then use cached results..
135
			if ($query)
136
			{
137
				$this->query($query);
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Mmanager\Extensions\Database\ezSQLcore as the method query() does only exist in the following sub-classes of Mmanager\Extensions\Database\ezSQLcore: Mmanager\Extensions\Database\ezSQL_mysqli. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
138
			}
139
140
			// Extract var out of cached results based x,y vals
141
			if ($this->last_result[$y])
142
			{
143
				$values = array_values(get_object_vars($this->last_result[$y]));
144
			}
145
146
			// If there is a value return it else return null
147
			return (isset($values[$x]) && $values[$x] !== '') ? $values[$x] : null;
148
		}
149
150
		/**********************************************************************
151
		*  Get one row from the DB - see docs for more detail
152
		*/
153
154
		function get_row($query = null, $output = OBJECT, $y = 0)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
155
		{
156
157
			// Log how the function was called
158
			$this->func_call = "\$db->get_row(\"$query\",$output,$y)";
159
160
			// If there is a query then perform it if not then use cached results..
161
			if ($query)
162
			{
163
				$this->query($query);
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Mmanager\Extensions\Database\ezSQLcore as the method query() does only exist in the following sub-classes of Mmanager\Extensions\Database\ezSQLcore: Mmanager\Extensions\Database\ezSQL_mysqli. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
164
			}
165
166
			// If the output is an object then return object using the row offset..
167
			if ($output == OBJECT)
168
			{
169
				return $this->last_result[$y] ? $this->last_result[$y] : null;
170
			}
171
			// If the output is an associative array then return row as such..
172
			elseif ($output == ARRAY_A)
173
			{
174
				return $this->last_result[$y] ?get_object_vars($this->last_result[$y]) : null;
175
			}
176
			// If the output is an numerical array then return row as such..
177
			elseif ($output == ARRAY_N)
178
			{
179
				return $this->last_result[$y] ?array_values(get_object_vars($this->last_result[$y])) : null;
180
			}
181
			// If invalid output type was specified..
182
			else
183
			{
184
				$this->show_errors ? trigger_error(" \$db->get_row(string query, output type, int offset) -- Output type must be one of: OBJECT, ARRAY_A, ARRAY_N", E_USER_WARNING) : null;
185
			}
186
187
		}
188
189
		/**********************************************************************
190
		*  Function to get 1 column from the cached result set based in X index
191
		*  see docs for usage and info
192
		*/
193
194
		function get_col($query = null, $x = 0)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
195
		{
196
197
			$new_array = array();
198
199
			// If there is a query then perform it if not then use cached results..
200
			if ($query)
201
			{
202
				$this->query($query);
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Mmanager\Extensions\Database\ezSQLcore as the method query() does only exist in the following sub-classes of Mmanager\Extensions\Database\ezSQLcore: Mmanager\Extensions\Database\ezSQL_mysqli. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
203
			}
204
205
			// Extract the column values
206
			$j = count($this->last_result);
207
			for ($i = 0; $i < $j; $i++)
208
			{
209
				$new_array[$i] = $this->get_var(null, $x, $i);
210
			}
211
212
			return $new_array;
213
		}
214
215
216
		/**********************************************************************
217
		*  Return the the query as a result set - see docs for more details
218
		*/
219
220
		function get_results($query = null, $output = OBJECT)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
221
		{
222
223
			// Log how the function was called
224
			$this->func_call = "\$db->get_results(\"$query\", $output)";
225
226
			// If there is a query then perform it if not then use cached results..
227
			if ($query)
228
			{
229
				$this->query($query);
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Mmanager\Extensions\Database\ezSQLcore as the method query() does only exist in the following sub-classes of Mmanager\Extensions\Database\ezSQLcore: Mmanager\Extensions\Database\ezSQL_mysqli. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
230
			}
231
232
			// Send back array of objects. Each row is an object
233
			if ($output == OBJECT)
234
			{
235
				return $this->last_result;
236
			}
237
			elseif ($output == ARRAY_A || $output == ARRAY_N)
238
			{
239
				if ($this->last_result)
240
				{
241
					$i = 0;
242
					foreach ($this->last_result as $row)
243
					{
244
245
						$new_array[$i] = get_object_vars($row);
0 ignored issues
show
Coding Style Comprehensibility introduced by
$new_array was never initialized. Although not strictly required by PHP, it is generally a good practice to add $new_array = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
246
247
						if ($output == ARRAY_N)
248
						{
249
							$new_array[$i] = array_values($new_array[$i]);
0 ignored issues
show
Bug introduced by
The variable $new_array does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
250
						}
251
252
						$i++;
253
					}
254
255
					return $new_array;
256
				} else
257
				{
258
					return array();
259
				}
260
			}
261
		}
262
263
264
		/**********************************************************************
265
		*  Function to get column meta data info pertaining to the last query
266
		* see docs for more info and usage
267
		*/
268
269
		function get_col_info($info_type = "name", $col_offset = -1)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
270
		{
271
272
			if ($this->col_info)
273
			{
274
				if ($col_offset == -1)
275
				{
276
					$i = 0;
277
					foreach ($this->col_info as $col)
278
					{
279
						$new_array[$i] = $col->{$info_type};
0 ignored issues
show
Coding Style Comprehensibility introduced by
$new_array was never initialized. Although not strictly required by PHP, it is generally a good practice to add $new_array = array(); before regardless.

Adding an explicit array definition is generally preferable to implicit array definition as it guarantees a stable state of the code.

Let’s take a look at an example:

foreach ($collection as $item) {
    $myArray['foo'] = $item->getFoo();

    if ($item->hasBar()) {
        $myArray['bar'] = $item->getBar();
    }

    // do something with $myArray
}

As you can see in this example, the array $myArray is initialized the first time when the foreach loop is entered. You can also see that the value of the bar key is only written conditionally; thus, its value might result from a previous iteration.

This might or might not be intended. To make your intention clear, your code more readible and to avoid accidental bugs, we recommend to add an explicit initialization $myArray = array() either outside or inside the foreach loop.

Loading history...
280
						$i++;
281
					}
282
					return $new_array;
0 ignored issues
show
Bug introduced by
The variable $new_array does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
283
				} else
284
				{
285
					return $this->col_info[$col_offset]->{$info_type};
286
				}
287
288
			}
289
290
		}
291
292
		/**********************************************************************
293
		*  store_cache
294
		*/
295
296
		function store_cache($query, $is_insert)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
297
		{
298
299
			// The would be cache file for this query
300
			$cache_file = $this->cache_dir.'/'.md5($query);
301
302
			// disk caching of queries
303
			if ($this->use_disk_cache && ($this->cache_queries && ! $is_insert) || ($this->cache_inserts && $is_insert))
304
			{
305
				if ( ! is_dir($this->cache_dir))
306
				{
307
					$this->register_error("Could not open cache dir: $this->cache_dir");
308
					$this->show_errors ? trigger_error("Could not open cache dir: $this->cache_dir", E_USER_WARNING) : null;
309
				}
310
				else
311
				{
312
					// Cache all result values
313
					$result_cache = array(
314
						'col_info' => $this->col_info,
315
						'last_result' => $this->last_result,
316
						'num_rows' => $this->num_rows,
0 ignored issues
show
Bug introduced by
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...
317
						'return_value' => $this->num_rows,
318
					);
319
					file_put_contents($cache_file, serialize($result_cache));
320
					if (file_exists($cache_file.".updating"))
321
						unlink($cache_file.".updating");
322
				}
323
			}
324
325
		}
326
327
		/**********************************************************************
328
		*  get_cache
329
		*/
330
331
		function get_cache($query)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
332
		{
333
334
			// The would be cache file for this query
335
			$cache_file = $this->cache_dir.'/'.md5($query);
336
337
			// Try to get previously cached version
338
			if ($this->use_disk_cache && file_exists($cache_file))
339
			{
340
				// Only use this cache file if less than 'cache_timeout' (hours)
341
				if ((time() - filemtime($cache_file)) > ($this->cache_timeout * 3600) &&
342
					! (file_exists($cache_file.".updating") && (time() - filemtime($cache_file.".updating") < 60)))
343
				{
344
					touch($cache_file.".updating"); // Show that we in the process of updating the cache
345
				}
346
				else
347
				{
348
					$result_cache = unserialize(file_get_contents($cache_file));
349
350
					$this->col_info = $result_cache['col_info'];
351
					$this->last_result = $result_cache['last_result'];
352
					$this->num_rows = $result_cache['num_rows'];
353
354
					$this->from_disk_cache = true;
355
356
					// If debug ALL queries
357
					$this->trace || $this->debug_all ? $this->debug() : null;
358
359
					return $result_cache['return_value'];
360
				}
361
			}
362
363
		}
364
365
		/**********************************************************************
366
		*  Dumps the contents of any input variable to screen in a nicely
367
		*  formatted and easy to understand way - any type: Object, Var or Array
368
		*/
369
370
		function vardump($mixed = '')
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
371
		{
372
373
			// Start outup buffering
374
			ob_start();
375
376
			echo "<p><table><tr><td bgcolor=ffffff><blockquote><font color=000090>";
377
			echo "<pre><font face=arial>";
378
379
			if ( ! $this->vardump_called)
380
			{
381
				echo "<font color=800080><b>ezSQL</b> (v".EZSQL_VERSION.") <b>Variable Dump..</b></font>\n\n";
382
			}
383
384
			$var_type = gettype($mixed);
385
			print_r(($mixed ? $mixed : "<font color=red>No Value / False</font>"));
386
			echo "\n\n<b>Type:</b> ".ucfirst($var_type)."\n";
387
			echo "<b>Last Query</b> [$this->num_queries]<b>:</b> ".($this->last_query ? $this->last_query : "NULL")."\n";
388
			echo "<b>Last Function Call:</b> ".($this->func_call ? $this->func_call : "None")."\n";
389
			echo "<b>Last Rows Returned:</b> ".count($this->last_result)."\n";
390
			echo "</font></pre></font></blockquote></td></tr></table>".$this->donation();
391
			echo "\n<hr size=1 noshade color=dddddd>";
392
393
			// Stop output buffering and capture debug HTML
394
			$html = ob_get_contents();
395
			ob_end_clean();
396
397
			// Only echo output if it is turned on
398
			if ($this->debug_echo_is_on)
399
			{
400
				echo $html;
401
			}
402
403
			$this->vardump_called = true;
404
405
			return $html;
406
407
		}
408
409
		/**********************************************************************
410
		*  Alias for the above function
411
		*/
412
413
		function dumpvar($mixed)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
414
		{
415
			$this->vardump($mixed);
416
		}
417
418
		/**********************************************************************
419
		*  Displays the last query string that was sent to the database & a
420
		* table listing results (if there were any).
421
		* (abstracted into a seperate file to save server overhead).
422
		*/
423
424
		function debug($print_to_screen = true)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
425
		{
426
427
			// Start outup buffering
428
			ob_start();
429
430
			echo "<blockquote>";
431
432
			// Only show ezSQL credits once..
433
			if ( ! $this->debug_called)
434
			{
435
				echo "<font color=800080 face=arial size=2><b>ezSQL</b> (v".EZSQL_VERSION.") <b>Debug..</b></font><p>\n";
436
			}
437
438
			if ($this->last_error)
439
			{
440
				echo "<font face=arial size=2 color=000099><b>Last Error --</b> [<font color=000000><b>$this->last_error</b></font>]<p>";
441
			}
442
443
			if ($this->from_disk_cache)
444
			{
445
				echo "<font face=arial size=2 color=000099><b>Results retrieved from disk cache</b></font><p>";
446
			}
447
448
			echo "<font face=arial size=2 color=000099><b>Query</b> [$this->num_queries] <b>--</b> ";
449
			echo "[<font color=000000><b>$this->last_query</b></font>]</font><p>";
450
451
				echo "<font face=arial size=2 color=000099><b>Query Result..</b></font>";
452
				echo "<blockquote>";
453
454
			if ($this->col_info)
455
			{
456
457
				// =====================================================
458
				// Results top rows
459
460
				echo "<table cellpadding=5 cellspacing=1 bgcolor=555555>";
461
				echo "<tr bgcolor=eeeeee><td nowrap valign=bottom><font color=555599 face=arial size=2><b>(row)</b></font></td>";
462
463
464
				for ($i = 0, $j = count($this->col_info); $i < $j; $i++)
465
				{
466
					/* when selecting count(*) the maxlengh is not set, size is set instead. */
467
					echo "<td nowrap align=left valign=top><font size=1 color=555599 face=arial>{$this->col_info[$i]->type}";
468
					if ( ! isset($this->col_info[$i]->max_length))
469
					{
470
						echo "{$this->col_info[$i]->size}";
471
					} else {
472
						echo "{$this->col_info[$i]->max_length}";
473
					}
474
					echo "</font><br><span style='font-family: arial; font-size: 10pt; font-weight: bold;'>{$this->col_info[$i]->name}</span></td>";
475
				}
476
477
				echo "</tr>";
478
479
				// ======================================================
480
				// print main results
481
482
			if ($this->last_result)
483
			{
484
485
				$i = 0;
486
				foreach ($this->get_results(null, ARRAY_N) as $one_row)
487
				{
488
					$i++;
489
					echo "<tr bgcolor=ffffff><td bgcolor=eeeeee nowrap align=middle><font size=2 color=555599 face=arial>$i</font></td>";
490
491
					foreach ($one_row as $item)
492
					{
493
						echo "<td nowrap><font face=arial size=2>$item</font></td>";
494
					}
495
496
					echo "</tr>";
497
				}
498
499
			} // if last result
500
			else
501
			{
502
				echo "<tr bgcolor=ffffff><td colspan=".(count($this->col_info) + 1)."><font face=arial size=2>No Results</font></td></tr>";
503
			}
504
505
			echo "</table>";
506
507
			} // if col_info
508
			else
509
			{
510
				echo "<font face=arial size=2>No Results</font>";
511
			}
512
513
			echo "</blockquote></blockquote>".$this->donation()."<hr noshade color=dddddd size=1>";
514
515
			// Stop output buffering and capture debug HTML
516
			$html = ob_get_contents();
517
			ob_end_clean();
518
519
			// Only echo output if it is turned on
520
			if ($this->debug_echo_is_on && $print_to_screen)
521
			{
522
				echo $html;
523
			}
524
525
			$this->debug_called = true;
526
527
			return $html;
528
529
		}
530
531
		/**********************************************************************
532
		*  Naughty little function to ask for some remuniration!
533
		*/
534
535
		function donation()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
536
		{
537
			return "<font size=1 face=arial color=000000>If ezSQL has helped <a href=\"https://www.paypal.com/xclick/business=justin%40justinvincent.com&item_name=ezSQL&no_note=1&tax=0\" style=\"color: 0000CC;\">make a donation!?</a> &nbsp;&nbsp;<!--[ go on! you know you want to! ]--></font>";
538
		}
539
540
		/**********************************************************************
541
		*  Timer related functions
542
		*/
543
544
		function timer_get_cur()
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
545
		{
546
			list($usec, $sec) = explode(" ", microtime());
547
			return ((float) $usec + (float) $sec);
548
		}
549
550
		function timer_start($timer_name)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
551
		{
552
			$this->timers[$timer_name] = $this->timer_get_cur();
553
		}
554
555
		function timer_elapsed($timer_name)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
556
		{
557
			return round($this->timer_get_cur() - $this->timers[$timer_name], 2);
558
		}
559
560
		function timer_update_global($timer_name)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
561
		{
562
			if ($this->do_profile)
563
			{
564
				$this->profile_times[] = array(
565
					'query' => $this->last_query,
566
					'time' => $this->timer_elapsed($timer_name)
567
				);
568
			}
569
570
			$this->total_query_time += $this->timer_elapsed($timer_name);
571
		}
572
573
		/**********************************************************************
574
		* Creates a SET nvp sql string from an associative array (and escapes all values)
575
		*
576
		*  Usage:
577
		*
578
		*     $db_data = array('login'=>'jv','email'=>'[email protected]', 'user_id' => 1, 'created' => 'NOW()');
579
		*
580
		*     $db->query("INSERT INTO users SET ".$db->get_set($db_data));
581
		*
582
		*     ...OR...
583
		*
584
		*     $db->query("UPDATE users SET ".$db->get_set($db_data)." WHERE user_id = 1");
585
		*
586
		* Output:
587
		*
588
		*     login = 'jv', email = '[email protected]', user_id = 1, created = NOW()
589
		*/
590
591
		function get_set($params)
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
592
		{
593
			if ( ! is_array($params))
594
			{
595
				$this->register_error('get_set() parameter invalid. Expected array in '.__FILE__.' on line '.__LINE__);
596
				return;
597
			}
598
			$sql = array();
599
			foreach ($params as $field => $val)
600
			{
601
				if ($val === 'true' || $val === true)
602
					$val = 1;
603
				if ($val === 'false' || $val === false)
604
					$val = 0;
605
606
				switch ($val) {
607
					case 'NOW()' :
608
					case 'NULL' :
609
					  $sql[] = "$field = $val";
610
						break;
611
					default :
612
						$sql[] = "$field = '".$this->escape($val)."'";
0 ignored issues
show
Bug introduced by
It seems like you code against a specific sub-type and not the parent class Mmanager\Extensions\Database\ezSQLcore as the method escape() does only exist in the following sub-classes of Mmanager\Extensions\Database\ezSQLcore: Mmanager\Extensions\Database\ezSQL_mysqli. Maybe you want to instanceof check for one of these explicitly?

Let’s take a look at an example:

abstract class User
{
    /** @return string */
    abstract public function getPassword();
}

class MyUser extends User
{
    public function getPassword()
    {
        // return something
    }

    public function getDisplayName()
    {
        // return some name.
    }
}

class AuthSystem
{
    public function authenticate(User $user)
    {
        $this->logger->info(sprintf('Authenticating %s.', $user->getDisplayName()));
        // do something.
    }
}

In the above example, the authenticate() method works fine as long as you just pass instances of MyUser. However, if you now also want to pass a different sub-classes of User which does not have a getDisplayName() method, the code will break.

Available Fixes

  1. Change the type-hint for the parameter:

    class AuthSystem
    {
        public function authenticate(MyUser $user) { /* ... */ }
    }
    
  2. Add an additional type-check:

    class AuthSystem
    {
        public function authenticate(User $user)
        {
            if ($user instanceof MyUser) {
                $this->logger->info(/** ... */);
            }
    
            // or alternatively
            if ( ! $user instanceof MyUser) {
                throw new \LogicException(
                    '$user must be an instance of MyUser, '
                   .'other instances are not supported.'
                );
            }
    
        }
    }
    
Note: PHP Analyzer uses reverse abstract interpretation to narrow down the types inside the if block in such a case.
  1. Add the method to the parent class:

    abstract class User
    {
        /** @return string */
        abstract public function getPassword();
    
        /** @return string */
        abstract public function getDisplayName();
    }
    
Loading history...
613
				}
614
			}
615
616
			return implode(', ', $sql);
617
		}
618
619
		/**
620
		 * Function for operating query count
621
		 *
622
		 * @param bool $all Set to false for function to return queries only during this connection
623
		 * @param bool $increase Set to true to increase query count (internal usage)
624
		 * @return int Returns query count base on $all
625
		 */
626
		function count($all = true, $increase = false) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
627
			if ($increase) {
628
				$this->num_queries++;
629
				$this->conn_queries++;
630
			}
631
632
			return ($all) ? $this->num_queries : $this->conn_queries;
633
		}
634
	}
635