This project does not seem to handle request data directly as such no vulnerable execution paths were found.
include
, or for example
via PHP's auto-loading mechanism.
These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more
1 | <?php |
||
2 | // Set include path in __construct |
||
3 | //require_once('adodb/adodb.inc.php'); |
||
4 | require_once(dirname(__FILE__) . '/fwolflib.php'); |
||
5 | require_once(dirname(__FILE__) . '/sql_generator.php'); |
||
6 | require_once(dirname(__FILE__) . '/../func/ecl.php'); |
||
7 | require_once(dirname(__FILE__) . '/../func/string.php'); |
||
8 | |||
9 | |||
10 | /** |
||
11 | * Extended ADODB class |
||
12 | * |
||
13 | * Include all ADODB had, and add a little others. |
||
14 | * |
||
15 | * Piror use this class' method and property, if the get/set/call target |
||
16 | * is not exists, use original ADODB's, this can be done by php's mechematic |
||
17 | * of overload __call __get __set. |
||
18 | * |
||
19 | * 这似乎是extend ADODB的一种比较好的方式,比官方网站文档上给的按不同数据库来继承子类的方式, |
||
20 | * 我认为要更方便一些。缺点是没有对RecordSet对象进行处理。 |
||
21 | * |
||
22 | * Adodb for Sybase bug: |
||
23 | * Affected_Rows() in windows 2003 不可用,httpd 进程会出错中止 |
||
24 | * |
||
25 | * 执行sql查询的系列更改中,限定系统/HTML/PHP使用$sSysCharset指定的编码,涉及函数列在__call()中, |
||
26 | * 但一些通过数组等其它方式传递参数的ADODB方法仍然无法通过这种方式实现sql编码自动转换。 |
||
27 | * |
||
28 | * 执行返回的数据还是需要转码的,不过返回数据的种类太多,放在应用中实现更简单一些,这里不自动执行, |
||
29 | * 只提供一个EncodingConvert方法供用户调用。 |
||
30 | * |
||
31 | * @deprecated Use Fwlib\Bridge\Adodb |
||
32 | * @package fwolflib |
||
33 | * @subpackage class |
||
34 | * @copyright Copyright 2008-2012, Fwolf |
||
35 | * @author Fwolf <[email protected]> |
||
36 | * @since 2008-04-08 |
||
37 | */ |
||
38 | class Adodb extends Fwolflib { |
||
0 ignored issues
–
show
|
|||
39 | |||
40 | /** |
||
41 | * Real ADODB connection object |
||
42 | * @var object |
||
43 | */ |
||
44 | protected $__conn = null; |
||
45 | |||
46 | /** |
||
47 | * Db profile |
||
48 | * @var array |
||
49 | */ |
||
50 | public $aDbProfile = null; |
||
51 | |||
52 | /** |
||
53 | * Table schema |
||
54 | * |
||
55 | * array( |
||
56 | * col -> // ADOFieldObject Object, not Array ! |
||
57 | * [name] => ts |
||
58 | * [max_length] => -1 |
||
59 | * [type] => timestamp |
||
60 | * [scale] => |
||
61 | * [not_null] => 1 |
||
62 | * [primary_key] => |
||
63 | * [auto_increment] => |
||
64 | * [binary] => |
||
65 | * [unsigned] => |
||
66 | * [zerofill] => |
||
67 | * [has_default] => 1 |
||
68 | * [default_value] => CURRENT_TIMESTAMP |
||
69 | * ) |
||
70 | * ) |
||
71 | * @var array |
||
72 | */ |
||
73 | public $aMetaColumn = array(); |
||
74 | |||
75 | /** |
||
76 | * Table column name array, index is upper case of column name |
||
77 | * |
||
78 | * eg: array( |
||
79 | * 'COLUMN' => 'column', |
||
80 | * ) |
||
81 | * @var array |
||
82 | */ |
||
83 | public $aMetaColumnName = array(); |
||
84 | |||
85 | /** |
||
86 | * Primary key columns of table |
||
87 | * |
||
88 | * array( |
||
89 | * tbl_name -> 'col_pk', |
||
90 | * tbl_name -> array(pk_col1, pk_col2), |
||
91 | * ) |
||
92 | * @var array |
||
93 | */ |
||
94 | public $aMetaPrimaryKey = array(); |
||
95 | |||
96 | /** |
||
97 | * Sql generator object |
||
98 | * @var object |
||
99 | */ |
||
100 | protected $oSg; |
||
101 | |||
102 | /** |
||
103 | * Error msg |
||
104 | * @var string |
||
105 | */ |
||
106 | public $sErrorMsg = ''; |
||
107 | |||
108 | /** |
||
109 | * System charset |
||
110 | * |
||
111 | * In common, this is your php script/operation system charset |
||
112 | * @var string |
||
113 | */ |
||
114 | public $sSysCharset = 'utf8'; |
||
115 | |||
116 | |||
117 | /** |
||
118 | * construct |
||
119 | * |
||
120 | * <code> |
||
121 | * $dbprofile = array(type, host, user, pass, name, lang); |
||
122 | * type is mysql/sybase_ase etc, |
||
123 | * name is dbname to select, |
||
124 | * lang is db server charset. |
||
125 | * </code> |
||
126 | * @var param array $dbprofile |
||
127 | * @var param string $path_adodb Include path of original ADODB |
||
128 | */ |
||
129 | public function __construct ($dbprofile, $path_adodb = '') { |
||
130 | parent::__construct(); |
||
131 | |||
132 | // Include original adodb lib |
||
133 | if (empty($path_adodb)) |
||
134 | $path_adodb = 'adodb/adodb.inc.php'; |
||
135 | require_once($path_adodb); |
||
136 | |||
137 | $this->aDbProfile = $dbprofile; |
||
138 | $this->__conn = ADONewConnection($dbprofile['type']); |
||
139 | |||
140 | // Sql generator object |
||
141 | $this->oSg = new SqlGenerator($this); |
||
0 ignored issues
–
show
The class
SqlGenerator has been deprecated with message: Use Fwlib\Db\SqlGenerator
This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead. ![]() |
|||
142 | } // end of class __construct |
||
143 | |||
144 | |||
145 | /** |
||
146 | * Overload __call, redirect method call to adodb |
||
147 | * |
||
148 | * @var string $name Method name |
||
149 | * @var array $arg Method argument |
||
150 | * @global int $i_db_query_times |
||
151 | * @return mixed |
||
152 | */ |
||
153 | public function __call ($name, $arg) { |
||
154 | // Before call, convert $sql encoding first |
||
155 | if ($this->sSysCharset != $this->aDbProfile['lang']) { |
||
156 | // Method list by ADODB doc order |
||
157 | // $sql is the 1st param |
||
158 | if (in_array($name, array('Execute', |
||
159 | 'CacheExecute', |
||
160 | 'SelectLimit', |
||
161 | 'CacheSelectLimit', |
||
162 | 'Prepare', |
||
163 | 'PrepareSP', |
||
164 | 'GetOne', |
||
165 | 'GetRow', |
||
166 | 'GetAll', |
||
167 | 'GetCol', |
||
168 | 'CacheGetOne', |
||
169 | 'CacheGetRow', |
||
170 | 'CacheGetAll', |
||
171 | 'CacheGetCol', |
||
172 | 'GetAssoc', |
||
173 | 'CacheGetAssoc', |
||
174 | 'ExecuteCursor', |
||
175 | ))) |
||
176 | $arg[0] = mb_convert_encoding($arg[0], $this->aDbProfile['lang'], $this->sSysCharset); |
||
177 | |||
178 | // $sql is the 2nd param |
||
179 | if (in_array($name, array('CacheExecute', |
||
180 | 'CacheSelectLimit', |
||
181 | 'CacheGetOne', |
||
182 | 'CacheGetRow', |
||
183 | 'CacheGetAll', |
||
184 | 'CacheGetCol', |
||
185 | 'CacheGetAssoc', |
||
186 | ))) |
||
187 | $arg[1] = mb_convert_encoding($arg[1], $this->aDbProfile['lang'], $this->sSysCharset); |
||
188 | } |
||
189 | |||
190 | // Count db query times |
||
191 | // Use global var so multi Adodb object can be included in count. |
||
192 | // (Done in func now) |
||
193 | // Use standalone func to can be easy extend by sub class. |
||
194 | View Code Duplication | if (in_array($name, array( |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
195 | 'Execute', 'SelectLimit', 'GetOne', 'GetRow', 'GetAll', |
||
196 | 'GetCol', 'GetAssoc', 'ExecuteCursor' |
||
197 | ))) |
||
198 | $this->CountDbQueryTimes(); |
||
199 | |||
200 | return call_user_func_array(array($this->__conn, $name), $arg); |
||
201 | } // end of func __call |
||
202 | |||
203 | |||
204 | /** |
||
205 | * Overload __get, redirect method call to adodb |
||
206 | * |
||
207 | * @param string $name |
||
208 | * @return mixed |
||
209 | */ |
||
210 | public function __get ($name) { |
||
211 | return $this->__conn->$name; |
||
212 | } // end of func __get |
||
213 | |||
214 | |||
215 | /** |
||
216 | * Overload __set, redirect method call to adodb |
||
217 | * |
||
218 | * @param string $name |
||
219 | * @param mixed $val |
||
220 | */ |
||
221 | public function __set ($name, $val) { |
||
222 | $this->__conn->$name = $val; |
||
223 | } // end of func __set |
||
224 | |||
225 | |||
226 | /** |
||
227 | } |
||
228 | * Connect, Add mysql 'set names utf8' |
||
229 | * |
||
230 | * <code> |
||
231 | * Obmit params(dbprofile was set in __construct): |
||
232 | * param $argHostname Host to connect to |
||
233 | * param $argUsername Userid to login |
||
234 | * param $argPassword Associated password |
||
235 | * param $argDatabaseName database |
||
236 | * </code> |
||
237 | * @param $forcenew Force new connection |
||
238 | * @return boolean |
||
239 | */ |
||
240 | public function Connect ($forcenew = false) { |
||
241 | // Mysqli doesn't allow port in host, grab it out and set |
||
242 | View Code Duplication | if ('mysqli' == strtolower($this->__conn->databaseType)) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
243 | $ar = array(); |
||
244 | $i = preg_match('/:(\d+)$/', $this->aDbProfile['host'], $ar); |
||
245 | if (0 < $i) { |
||
246 | $this->__conn->port = $ar[1]; |
||
247 | $this->aDbProfile['host'] = preg_replace('/:(\d+)$/', '' |
||
248 | , $this->aDbProfile['host']); |
||
249 | } |
||
250 | } |
||
251 | |||
252 | |||
253 | try { |
||
254 | // Disable error display tempratory |
||
255 | $s = ini_get("display_errors"); |
||
256 | ini_set("display_errors", "0"); |
||
257 | |||
258 | // Sybase will echo 'change to master' warning msg |
||
259 | // :THINK: Will this problem solved if we drop default |
||
260 | // database master from sa user ? |
||
261 | if ($this->IsDbSybase()) { |
||
262 | $rs = $this->__conn->Connect($this->aDbProfile['host'], |
||
263 | $this->aDbProfile['user'], |
||
264 | $this->aDbProfile['pass'], |
||
265 | $this->aDbProfile['name'], |
||
266 | $forcenew); |
||
267 | } |
||
268 | else { |
||
269 | $rs = $this->__conn->Connect($this->aDbProfile['host'], |
||
270 | $this->aDbProfile['user'], |
||
271 | $this->aDbProfile['pass'], |
||
272 | $this->aDbProfile['name'], |
||
273 | $forcenew); |
||
274 | } |
||
275 | |||
276 | // Recover original error display setting |
||
277 | ini_set("display_errors", $s); |
||
278 | |||
279 | if (empty($rs)) { |
||
280 | throw new Exception('Db connect fail, please check php errorlog.', -1); |
||
281 | } |
||
282 | } catch (Exception $e) { |
||
283 | // Get error trace message |
||
284 | $i_ob = ob_get_level(); |
||
285 | if (0 != $i_ob) |
||
286 | $s_t = ob_get_clean(); |
||
287 | |||
288 | ob_start(); |
||
289 | adodb_backtrace($e->getTrace()); |
||
290 | $s_trace = ob_get_clean(); |
||
291 | |||
292 | if (0 != $i_ob) { |
||
293 | // Maybe cause error if output handle of ob_start used before |
||
294 | ob_start(); |
||
295 | echo $s_t; |
||
0 ignored issues
–
show
The variable
$s_t 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
![]() |
|||
296 | } |
||
297 | |||
298 | |||
299 | // Log error |
||
300 | $s_trace = "======== Adodb db connect error\n" |
||
301 | . str_replace(' ', '>', strip_tags($s_trace)) |
||
302 | . $this->ErrorMsg() . "\n"; |
||
0 ignored issues
–
show
The method
ErrorMsg does not exist on object<Adodb> ? Since you implemented __call , maybe consider adding a @method annotation.
If you implement This is often the case, when class ParentClass {
private $data = array();
public function __call($method, array $args) {
if (0 === strpos($method, 'get')) {
return $this->data[strtolower(substr($method, 3))];
}
throw new \LogicException(sprintf('Unsupported method: %s', $method));
}
}
/**
* If this class knows which fields exist, you can specify the methods here:
*
* @method string getName()
*/
class SomeClass extends ParentClass { }
![]() |
|||
303 | $this->sErrorMsg = $s_trace; |
||
304 | error_log($s_trace); |
||
305 | |||
306 | /* |
||
307 | // Print error |
||
308 | $this->sErrorMsg = 'Error, code ' |
||
309 | . $e->getCode() |
||
310 | . ', msg: ' . $e->getMessage(); |
||
311 | |||
312 | // Log error |
||
313 | $s_trace = str_replace(' ', '>', strip_tags($s_trace)); |
||
314 | error_log(''); |
||
315 | error_log('======== Adodb db connect error'); |
||
316 | error_log("\n" . $s_trace); |
||
317 | error_log($this->sErrorMsg); |
||
318 | //error_log(''); |
||
319 | */ |
||
320 | |||
321 | //var_dump($e); |
||
322 | //echo $e; |
||
323 | if (0 != $i_ob) { |
||
324 | ob_end_flush(); |
||
325 | } |
||
326 | //exit(); |
||
327 | return false; |
||
328 | } |
||
329 | |||
330 | // 针对mysql 4.1以上,UTF8编码的数据库,需要在连接后指定编码 |
||
331 | // Can also use $this->aDbProfile['type'] |
||
332 | // mysql, mysqli |
||
333 | if ($this->IsDbMysql()) { |
||
334 | $this->__conn->Execute('set names "' . str_replace('utf-8', 'utf8', $this->aDbProfile['lang']) . '"'); |
||
335 | } |
||
336 | |||
337 | //return $rs; |
||
338 | return true; |
||
339 | } // end of func Connect |
||
340 | |||
341 | |||
342 | /** |
||
343 | * Count how many db query have executed |
||
344 | * |
||
345 | * This function can be extend by subclass if you want to count on multi db objects. |
||
346 | * |
||
347 | * Can't count in Adodb::property, because need display is done by Controler, |
||
348 | * which will call View, but Adodb is property of Module, |
||
349 | * so we can only use global vars to save this value. |
||
350 | * @global int $i_db_query_times |
||
351 | */ |
||
352 | protected function CountDbQueryTimes () { |
||
353 | global $i_db_query_times; |
||
354 | $i_db_query_times ++; |
||
355 | } // end of func CountDbQueryTimes |
||
356 | |||
357 | |||
358 | /** |
||
359 | * Delete rows by condition user given |
||
360 | * |
||
361 | * @param string $tbl |
||
362 | * @param string $cond Condition, can be where, having etc, raw sql string, not null. |
||
363 | * @return int -1 error/0 not found/N > 0 number of rows |
||
364 | */ |
||
365 | View Code Duplication | public function DelRow ($tbl, $cond) { |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
366 | $cond = trim($cond); |
||
367 | if (empty($cond)) |
||
368 | return -1; |
||
369 | $this->PExecute($this->GenSql(array( |
||
370 | 'DELETE' => $tbl, |
||
371 | )) . ' ' . $cond); |
||
372 | if (0 != $this->ErrorNo()) |
||
0 ignored issues
–
show
The method
ErrorNo does not exist on object<Adodb> ? Since you implemented __call , maybe consider adding a @method annotation.
If you implement This is often the case, when class ParentClass {
private $data = array();
public function __call($method, array $args) {
if (0 === strpos($method, 'get')) {
return $this->data[strtolower(substr($method, 3))];
}
throw new \LogicException(sprintf('Unsupported method: %s', $method));
}
}
/**
* If this class knows which fields exist, you can specify the methods here:
*
* @method string getName()
*/
class SomeClass extends ParentClass { }
![]() |
|||
373 | // Execute error |
||
374 | return -1; |
||
375 | else |
||
376 | return $this->Affected_Rows(); |
||
0 ignored issues
–
show
The method
Affected_Rows does not exist on object<Adodb> ? Since you implemented __call , maybe consider adding a @method annotation.
If you implement This is often the case, when class ParentClass {
private $data = array();
public function __call($method, array $args) {
if (0 === strpos($method, 'get')) {
return $this->data[strtolower(substr($method, 3))];
}
throw new \LogicException(sprintf('Unsupported method: %s', $method));
}
}
/**
* If this class knows which fields exist, you can specify the methods here:
*
* @method string getName()
*/
class SomeClass extends ParentClass { }
![]() |
|||
377 | } // end of func DelRow |
||
378 | |||
379 | |||
380 | /** |
||
381 | * Convert recordset(simple array) or other string |
||
382 | * from db encoding to system encoding |
||
383 | * |
||
384 | * Use recursive mechanism, beware of loop hole. |
||
385 | * @param mixed &$s Source to convert |
||
386 | * @return mixed |
||
387 | */ |
||
388 | View Code Duplication | public function EncodingConvert (&$s) { |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
389 | if (is_array($s) && !empty($s)) { |
||
390 | foreach ($s as &$val) |
||
391 | $this->EncodingConvert($val); |
||
392 | unset($val); |
||
393 | } |
||
394 | |||
395 | if (is_string($s)) { |
||
396 | if ($this->sSysCharset != $this->aDbProfile['lang']) |
||
397 | $s = mb_convert_encoding($s, $this->sSysCharset, $this->aDbProfile['lang']); |
||
398 | } |
||
399 | return $s; |
||
400 | } // end of func EncodingConvert |
||
401 | |||
402 | |||
403 | /** |
||
404 | * Convert data encoding |
||
405 | * from system(usually utf-8) to db |
||
406 | * |
||
407 | * Use recursive mechanism, beware of loop hole. |
||
408 | * @param mixed &$s Source to convert |
||
409 | * @return mixed |
||
410 | */ |
||
411 | View Code Duplication | public function EncodingConvertReverse (&$s) { |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
412 | if (is_array($s) && !empty($s)) { |
||
413 | foreach ($s as &$val) |
||
414 | $this->EncodingConvertReverse($val); |
||
415 | unset($val); |
||
416 | } |
||
417 | |||
418 | if (is_string($s)) { |
||
419 | if ($this->sSysCharset != $this->aDbProfile['lang']) |
||
420 | $s = mb_convert_encoding($s, $this->aDbProfile['lang'], $this->sSysCharset); |
||
421 | } |
||
422 | return $s; |
||
423 | } // end of func EncodingConvertReverse |
||
424 | |||
425 | |||
426 | /** |
||
427 | * Generate SQL then exec it |
||
428 | * |
||
429 | * @param array $ar_sql Same as GenSql() |
||
430 | * @return object |
||
431 | * @see GenSql() |
||
432 | */ |
||
433 | public function ExecuteGenSql ($ar_sql) { |
||
434 | return $this->Execute($this->GenSql($ar_sql)); |
||
0 ignored issues
–
show
|
|||
435 | } // end of func ExecuteGenSql |
||
436 | |||
437 | |||
438 | /** |
||
439 | * Find name of timestamp column of a table |
||
440 | * |
||
441 | * @param $tbl Table name |
||
442 | * @return string |
||
443 | */ |
||
444 | public function FindColTs ($tbl) { |
||
445 | $ar_col = $this->GetMetaColumn($tbl); |
||
446 | if (empty($ar_col)) |
||
447 | return ''; |
||
448 | |||
449 | if ($this->IsDbSybase()) { |
||
450 | // Sybase's timestamp column must be lower cased |
||
451 | // Can name as others, but name as 'timestamp' will auto got )timestamp) type. |
||
452 | /* |
||
453 | if (isset($ar_col['timestamp'])) |
||
454 | return 'timestamp'; |
||
455 | else |
||
456 | return ''; |
||
457 | */ |
||
458 | // New way: |
||
459 | // http://bbs.chinaunix.net/archiver/tid-930729.html |
||
460 | $rs = $this->ExecuteGenSql(array( |
||
461 | 'SELECT' => array( |
||
462 | 'name' => 'a.name', |
||
463 | 'length' => 'a.length', |
||
464 | 'usertype' => 'a.usertype', |
||
465 | 'type' => 'b.name', |
||
466 | 'tableName' => 'c.name', |
||
467 | ), |
||
468 | 'FROM' => array( |
||
469 | 'a' => 'syscolumns', |
||
470 | 'b' => 'systypes', |
||
471 | 'c' => 'sysobjects', |
||
472 | ), |
||
473 | 'WHERE' => array( |
||
474 | "a.id = c.id", |
||
475 | 'a.type = b.type', |
||
476 | 'a.usertype = b.usertype', |
||
477 | 'b.type = 37', |
||
478 | 'b.usertype = 80', |
||
479 | ), |
||
480 | )); |
||
481 | View Code Duplication | while (!empty($rs) && !$rs->EOF) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
482 | if ($tbl == $rs->fields['tableName']) { |
||
483 | return $rs->fields['name']; |
||
484 | } |
||
485 | $rs->MoveNext(); |
||
486 | } |
||
487 | |||
488 | return ''; |
||
489 | //select a.name,a.length,a.usertype,b.name AS type from syscolumns a ,systypes b |
||
490 | //where id = object_id('ztb_yh') and a.type=b.type and a.usertype = b.usertype |
||
491 | |||
492 | } |
||
493 | View Code Duplication | elseif ($this->IsDbMysql()) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
494 | // Check 'type' |
||
495 | foreach ($ar_col as $k => $v) |
||
496 | if (isset($v->type) && 'timestamp' == $v->type) |
||
497 | return $k; |
||
498 | } |
||
499 | else { |
||
500 | die("FindColTs not implemented!\n"); |
||
501 | } |
||
502 | } // end of func FindColTs |
||
503 | |||
504 | |||
505 | /** |
||
506 | * Generate SQL statement |
||
507 | * |
||
508 | * User should avoid use SELECT/UPDATE/INSERT/DELETE simultaneously. |
||
509 | * |
||
510 | * Generate order by SQL statement format order. |
||
511 | * |
||
512 | * UPDATE/INSERT/DELETE is followed by [TBL_NAME], |
||
513 | * so need not use FROM. |
||
514 | * @param array $ar_sql Array(select=>..., from=>...) |
||
515 | * @return string |
||
516 | * @see SqlGenerator |
||
517 | */ |
||
518 | public function GenSql ($ar_sql) { |
||
519 | // Changed to use SqlGenerator |
||
520 | if (!empty($ar_sql)) { |
||
521 | return $this->oSg->GetSql($ar_sql); |
||
522 | } |
||
523 | else |
||
524 | return ''; |
||
525 | } // end of func GenSql |
||
526 | |||
527 | |||
528 | /** |
||
529 | * Generate SQL statement for Prepare |
||
530 | * |
||
531 | * value -> ? or :name, and quote chars removed |
||
532 | * @param array $ar_sql Same as GenSql() |
||
533 | * @return string |
||
534 | * @see GenSql() |
||
535 | * @see SqlGenerator |
||
536 | */ |
||
537 | public function GenSqlPrepare ($ar_sql) { |
||
538 | if (!empty($ar_sql)) |
||
539 | return $this->oSg->GetSqlPrepare($ar_sql); |
||
540 | else |
||
541 | return ''; |
||
542 | } // end of func GenSqlPrepare |
||
543 | |||
544 | |||
545 | /** |
||
546 | * Get data from single table using PK |
||
547 | * |
||
548 | * $m_pk, $col, $col_pk support string split by ',' or array, like: |
||
549 | * 1. 'val' |
||
550 | * 2. 'val1, val2' |
||
551 | * 3. array('val1', 'val2') |
||
552 | * |
||
553 | * '*' can be used for $col, means all cols in table, this way can't use |
||
554 | * cache, not recommend. |
||
555 | * |
||
556 | * Notice: $col must indexed by number start from 0. |
||
557 | * |
||
558 | * Also, this function can be used to retrieve data from a table with |
||
559 | * single unique index, by assigning $col_pk to non-PK column. |
||
560 | * |
||
561 | * @param string $s_tbl |
||
562 | * @param mixed $m_pk PK value |
||
563 | * @param mixed $col Cols need to retrieve. |
||
564 | * @param mixed $col_pk PK column name, NULL to auto get. |
||
565 | * @return mixed Single/array, NULL if error occur. |
||
566 | */ |
||
567 | public function GetDataByPk ($s_tbl, $m_pk, $col = NULL, $col_pk = NULL) { |
||
568 | // Treat PK col |
||
569 | if (empty($col_pk)) { |
||
570 | $col_pk = $this->GetMetaPrimaryKey($s_tbl); |
||
571 | } |
||
572 | |||
573 | // PK and col name all convert to array |
||
574 | View Code Duplication | if (!is_array($m_pk)) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
575 | if (is_string($m_pk)) |
||
576 | $m_pk = StrToArray($m_pk, ','); |
||
0 ignored issues
–
show
The function
StrToArray() has been deprecated with message: Use Fwlib\Util\StringUtil::toArray()
This function has been deprecated. The supplier of the file has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the function will be removed from the class and what other function to use instead. ![]() |
|||
577 | else |
||
578 | $m_pk = array($m_pk); |
||
579 | } |
||
580 | View Code Duplication | if (!is_array($col_pk)) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
581 | if (is_string($col_pk)) |
||
582 | $col_pk = StrToArray($col_pk, ','); |
||
0 ignored issues
–
show
The function
StrToArray() has been deprecated with message: Use Fwlib\Util\StringUtil::toArray()
This function has been deprecated. The supplier of the file has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the function will be removed from the class and what other function to use instead. ![]() |
|||
583 | else |
||
584 | $col_pk = array($col_pk); |
||
585 | } |
||
586 | |||
587 | // $col_pk need to be array same count with $m_pk |
||
588 | if (count($m_pk) != count($col_pk)) { |
||
589 | $this->Log('PK value and column not match.', 4); |
||
590 | return NULL; |
||
591 | } |
||
592 | |||
593 | // Treat col |
||
594 | if (empty($col)) |
||
595 | $col = '*'; |
||
596 | if ('*' == $col) |
||
597 | // Drop uppercased index |
||
598 | $col = array_values($this->GetMetaColumnName($s_tbl)); |
||
599 | View Code Duplication | if (!is_array($col)) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
600 | if (is_string($col)) |
||
601 | // String split by ',', style 'col AS col_alias' allowed |
||
602 | $col = StrToArray($col, ','); |
||
0 ignored issues
–
show
The function
StrToArray() has been deprecated with message: Use Fwlib\Util\StringUtil::toArray()
This function has been deprecated. The supplier of the file has supplied an explanatory message. The explanatory message should give you some clue as to whether and when the function will be removed from the class and what other function to use instead. ![]() |
|||
603 | else |
||
604 | $col = array($col); |
||
605 | } |
||
606 | |||
607 | // $m_pk, $col, $col_pk all converted to array |
||
608 | |||
609 | // Retrieve from db |
||
610 | $ar_sql = array( |
||
611 | 'SELECT' => $col, |
||
612 | 'FROM' => $s_tbl, |
||
613 | 'LIMIT' => 1, |
||
614 | ); |
||
615 | while (!empty($m_pk)) { |
||
616 | $s_col_pk = array_shift($col_pk); |
||
617 | $ar_sql['WHERE'][] = $s_col_pk . ' = ' |
||
618 | . $this->QuoteValue($s_tbl, $s_col_pk, array_shift($m_pk)); |
||
619 | unset($s_col_pk); |
||
620 | } |
||
621 | $rs = $this->ExecuteGenSql($ar_sql); |
||
622 | $ar_rs = array(); |
||
623 | if (!empty($rs) && !$rs->EOF) { |
||
624 | $ar_rs = $rs->GetRowAssoc(false); |
||
625 | } |
||
626 | |||
627 | // Return value |
||
628 | if (empty($ar_rs)) |
||
629 | return NULL; |
||
630 | else { |
||
631 | if (1 == count($ar_rs)) |
||
632 | return array_pop($ar_rs); |
||
633 | else |
||
634 | return $ar_rs; |
||
635 | } |
||
636 | } // end of func GetDataByPk |
||
637 | |||
638 | |||
639 | /** |
||
640 | * Get table schema |
||
641 | * |
||
642 | * @param string $table |
||
643 | * @param boolean $forcenew Force to retrieve instead of read from cache |
||
644 | * @return array |
||
645 | * @see $aMetaColumn |
||
646 | */ |
||
647 | public function GetMetaColumn ($table, $forcenew = false) { |
||
648 | if (!isset($this->aMetaColumn[$table]) || (true == $forcenew)) { |
||
0 ignored issues
–
show
|
|||
649 | $this->aMetaColumn[$table] = $this->MetaColumns($table); |
||
0 ignored issues
–
show
The method
MetaColumns does not exist on object<Adodb> ? Since you implemented __call , maybe consider adding a @method annotation.
If you implement This is often the case, when class ParentClass {
private $data = array();
public function __call($method, array $args) {
if (0 === strpos($method, 'get')) {
return $this->data[strtolower(substr($method, 3))];
}
throw new \LogicException(sprintf('Unsupported method: %s', $method));
}
}
/**
* If this class knows which fields exist, you can specify the methods here:
*
* @method string getName()
*/
class SomeClass extends ParentClass { }
![]() |
|||
650 | |||
651 | // Convert columns to native case |
||
652 | $col_name = $this->GetMetaColumnName($table); |
||
653 | // $col_name = array(COLUMN => column), $c is UPPER CASED |
||
654 | foreach ($this->aMetaColumn[$table] as $c => $ar) { |
||
655 | $this->aMetaColumn[$table][$col_name[$c]] = $ar; |
||
656 | unset($this->aMetaColumn[$table][$c]); |
||
657 | } |
||
658 | // Fix: sybase db display timestamp column as varbinary |
||
659 | View Code Duplication | if ($this->IsDbSybase()) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
660 | $s = $this->FindColTs($table); |
||
661 | if (!empty($s)) |
||
662 | $this->aMetaColumn[$table][$s]->type = 'timestamp'; |
||
663 | } |
||
664 | //print_r($this->aMetaColumn); |
||
665 | } |
||
666 | return $this->aMetaColumn[$table]; |
||
667 | } // end of func GetMetaColumn |
||
668 | |||
669 | |||
670 | /** |
||
671 | * Get table column name |
||
672 | * |
||
673 | * @param string $table |
||
674 | * @param boolean $forcenew Force to retrieve instead of read from cache |
||
675 | * @return array |
||
676 | * @see $aMetaColumnName |
||
677 | */ |
||
678 | public function GetMetaColumnName ($table, $forcenew = false) { |
||
679 | View Code Duplication | if (!isset($this->aMetaColumnName[$table]) || (true == $forcenew)) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
680 | $this->aMetaColumnName[$table] = $this->MetaColumnNames($table); |
||
0 ignored issues
–
show
The method
MetaColumnNames does not exist on object<Adodb> ? Since you implemented __call , maybe consider adding a @method annotation.
If you implement This is often the case, when class ParentClass {
private $data = array();
public function __call($method, array $args) {
if (0 === strpos($method, 'get')) {
return $this->data[strtolower(substr($method, 3))];
}
throw new \LogicException(sprintf('Unsupported method: %s', $method));
}
}
/**
* If this class knows which fields exist, you can specify the methods here:
*
* @method string getName()
*/
class SomeClass extends ParentClass { }
![]() |
|||
681 | } |
||
682 | return $this->aMetaColumnName[$table]; |
||
683 | } // end of func GetMetaColumnName |
||
684 | |||
685 | |||
686 | /** |
||
687 | * Get primary key column of a table |
||
688 | * |
||
689 | * @param string $table |
||
690 | * @param boolean $forcenew Force to retrieve instead of read from cache |
||
691 | * @return mixed Single string value or array when primary key contain multi columns. |
||
692 | * @see $aMetaPrimaryKey |
||
693 | */ |
||
694 | public function GetMetaPrimaryKey ($table, $forcenew = false) { |
||
695 | if (!isset($this->aMetaPrimaryKey[$table]) || (true == $forcenew)) { |
||
0 ignored issues
–
show
|
|||
696 | // Find using Adodb first |
||
697 | $ar = $this->MetaPrimaryKeys($table); |
||
0 ignored issues
–
show
The method
MetaPrimaryKeys does not exist on object<Adodb> ? Since you implemented __call , maybe consider adding a @method annotation.
If you implement This is often the case, when class ParentClass {
private $data = array();
public function __call($method, array $args) {
if (0 === strpos($method, 'get')) {
return $this->data[strtolower(substr($method, 3))];
}
throw new \LogicException(sprintf('Unsupported method: %s', $method));
}
}
/**
* If this class knows which fields exist, you can specify the methods here:
*
* @method string getName()
*/
class SomeClass extends ParentClass { }
![]() |
|||
698 | if (false == $ar || empty($ar)) { |
||
699 | // Adodb not support, find by hand |
||
700 | // Sybase |
||
701 | // keys1、keys2、keys3的描述不清,应该是: |
||
702 | // select name ,keycnt |
||
703 | // ,index_col(YourTableName,indid,1) --主键中的第一列 |
||
704 | // ,index_col(YourTableName,indid,2) --主键中的第二列,如果有的话 |
||
705 | // from sysindexes |
||
706 | // where status & 2048=2048 |
||
707 | // and id=object_id(YourTableName) |
||
708 | // 主键涉及的列的数量在keycnt中。如果主键索引不是簇集索引(由status中的0x10位决定)的话,则为keycnt-1。 |
||
709 | // http://topic.csdn.net/t/20030117/17/1369396.html |
||
710 | // 根据这种方法,目前好像只能用于主键包含三个以下字段的情况? |
||
711 | // 已测试过主键包含两个字段的情况下能取出来 |
||
712 | /* |
||
713 | select name, keycnt, index_col('sgqyjbqk', indid, 1) |
||
714 | , index_col('sgqyjbqk', indid, 2) |
||
715 | , index_col('sgqyjbqk', indid, 3) |
||
716 | from sysindexes |
||
717 | where status & 2048 = 2048 |
||
718 | and id = object_id('sgqyjbqk') |
||
719 | */ |
||
720 | View Code Duplication | if ($this->IsDbSybase()) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
721 | $rs = $this->PExecuteGenSql(array( |
||
722 | 'select' => array( |
||
723 | 'name' => 'a.name', |
||
724 | 'keycnt' => 'a.keycnt', |
||
725 | 'k1' => "index_col('$table', indid, 1)", |
||
726 | 'k2' => "index_col('$table', indid, 2)", |
||
727 | 'k3' => "index_col('$table', indid, 3)", |
||
728 | ), |
||
729 | 'from' => array( |
||
730 | 'a' => 'sysindexes', |
||
731 | 'b' => 'sysobjects', |
||
732 | ), |
||
733 | 'where' => array( |
||
734 | 'a.status & 2048 = 2048 ', |
||
735 | "b.name = '$table'", |
||
736 | "a.id = b.id" |
||
737 | ) |
||
738 | )); |
||
739 | if (true == $rs && 0 < $rs->RowCount()) { |
||
740 | // Got |
||
741 | $ar = array($rs->fields['k1']); |
||
742 | if (!empty($rs->fields['k2'])) |
||
743 | $ar[] = $rs->fields['k2']; |
||
744 | if (!empty($rs->fields['k3'])) |
||
745 | $ar[] = $rs->fields['k3']; |
||
746 | } |
||
747 | else { |
||
748 | // Table have no primary key |
||
749 | $ar = ''; |
||
750 | } |
||
751 | } |
||
752 | } |
||
753 | |||
754 | // Convert columns to native case |
||
755 | if (!empty($ar)) { |
||
756 | $col_name = $this->GetMetaColumnName($table); |
||
757 | // $col_name = array(COLUMN => column), $c is UPPER CASED |
||
758 | foreach ($ar as $idx => &$col) { |
||
759 | if ($col != $col_name[strtoupper($col)]) { |
||
760 | unset($ar[$idx]); |
||
761 | $ar[] = $col_name[strtoupper($col)]; |
||
762 | } |
||
763 | } |
||
764 | unset($col); |
||
765 | } |
||
766 | |||
767 | if (is_array($ar) && 1 == count($ar)) |
||
768 | // Only 1 primary key column |
||
769 | $ar = $ar[0]; |
||
770 | |||
771 | // Set to cache |
||
772 | if (!empty($ar)) |
||
773 | $this->aMetaPrimaryKey[$table] = $ar; |
||
774 | } |
||
775 | if (isset($this->aMetaPrimaryKey[$table])) |
||
776 | return $this->aMetaPrimaryKey[$table]; |
||
777 | else |
||
778 | return ''; |
||
779 | } // end of func GetMetaPrimaryKey |
||
780 | |||
781 | |||
782 | /** |
||
783 | * Get rows count by condition user given |
||
784 | * |
||
785 | * @param string $tbl |
||
786 | * @param string $cond Condition, can be where, having etc, raw sql string. |
||
787 | * @return int -1: error/N >= 0: number of rows |
||
788 | */ |
||
789 | View Code Duplication | public function GetRowCount ($tbl, $cond = '') { |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
790 | $rs = $this->PExecute($this->GenSql(array( |
||
791 | 'SELECT' => array('c' => 'count(1)'), |
||
792 | 'FROM' => $tbl, |
||
793 | )) . ' ' . $cond); |
||
794 | if (false == $rs || 0 != $this->ErrorNo() |
||
0 ignored issues
–
show
The method
ErrorNo does not exist on object<Adodb> ? Since you implemented __call , maybe consider adding a @method annotation.
If you implement This is often the case, when class ParentClass {
private $data = array();
public function __call($method, array $args) {
if (0 === strpos($method, 'get')) {
return $this->data[strtolower(substr($method, 3))];
}
throw new \LogicException(sprintf('Unsupported method: %s', $method));
}
}
/**
* If this class knows which fields exist, you can specify the methods here:
*
* @method string getName()
*/
class SomeClass extends ParentClass { }
![]() |
|||
795 | || 0 == $rs->RowCount()) |
||
796 | // Execute error |
||
797 | return -1; |
||
798 | else |
||
799 | return $rs->fields['c']; |
||
800 | } // end of func GetRowCount |
||
801 | |||
802 | |||
803 | /** |
||
804 | * Get delimiter between SQL for various db |
||
805 | * |
||
806 | * @return string |
||
807 | */ |
||
808 | public function GetSqlDelimiter () { |
||
809 | if ($this->IsDbMysql()) |
||
810 | return ";\n"; |
||
811 | elseif ($this->IsDbSybase()) |
||
812 | return "\n"; |
||
813 | else { |
||
814 | $this->Log('GetSqlDelimiter() for this kind of db not implement.' |
||
815 | , 5); |
||
816 | return "\n"; |
||
817 | } |
||
818 | } // end of func GetSqlDelimiter |
||
819 | |||
820 | |||
821 | /** |
||
822 | * Get SQL: begin transaction |
||
823 | * |
||
824 | * @return string |
||
825 | */ |
||
826 | public function GetSqlTransBegin () { |
||
827 | if ($this->IsDbMysql()) |
||
828 | return 'START TRANSACTION' . $this->GetSqlDelimiter(); |
||
829 | else |
||
830 | return 'BEGIN TRANSACTION' . $this->GetSqlDelimiter(); |
||
831 | } // end of func GetSqlTransBegin |
||
832 | |||
833 | |||
834 | /** |
||
835 | * Get SQL: commit transaction |
||
836 | * |
||
837 | * @return string |
||
838 | */ |
||
839 | public function GetSqlTransCommit () { |
||
840 | return 'COMMIT' . $this->GetSqlDelimiter(); |
||
841 | } // end of func GetSqlTransCommit |
||
842 | |||
843 | |||
844 | /** |
||
845 | * Get SQL: rollback transaction |
||
846 | * |
||
847 | * @return string |
||
848 | */ |
||
849 | public function GetSqlTransRollback () { |
||
850 | return 'ROLLBACK' . $this->GetSqlDelimiter(); |
||
851 | } // end of func GetSqlTransRollback |
||
852 | |||
853 | |||
854 | /** |
||
855 | * If current db is a mysql db. |
||
856 | * |
||
857 | * @return boolean |
||
858 | */ |
||
859 | public function IsDbMysql () { |
||
860 | return ('mysql' == substr($this->__conn->databaseType, 0, 5)); |
||
861 | } // end of func IsDbMysql |
||
862 | |||
863 | |||
864 | /** |
||
865 | * If current db is a sybase db. |
||
866 | * |
||
867 | * @return boolean |
||
868 | */ |
||
869 | public function IsDbSybase () { |
||
870 | return ('sybase' == substr($this->aDbProfile['type'], 0, 6)) || |
||
871 | ('pdo_sybase' == substr($this->aDbProfile['type'], 0, 10)); |
||
872 | } |
||
873 | |||
874 | |||
875 | /** |
||
876 | * Is timestamp column's value is unique |
||
877 | * |
||
878 | * @return boolean |
||
879 | */ |
||
880 | public function IsTsUnique () { |
||
881 | if ('sybase' == $this->IsDbSybase()) |
||
882 | return true; |
||
883 | else |
||
884 | // Mysql |
||
885 | return false; |
||
886 | } // end of func IsTsUnique |
||
887 | |||
888 | |||
889 | /** |
||
890 | * Prepare and execute sql |
||
891 | * |
||
892 | * @param string $sql |
||
893 | * @param array $inputarr Optional parameters in sql |
||
894 | * @return object |
||
895 | */ |
||
896 | public function PExecute ($sql, $inputarr = false) { |
||
897 | $stmt = $this->Prepare($sql); |
||
0 ignored issues
–
show
|
|||
898 | $this->BeginTrans(); |
||
0 ignored issues
–
show
The method
BeginTrans does not exist on object<Adodb> ? Since you implemented __call , maybe consider adding a @method annotation.
If you implement This is often the case, when class ParentClass {
private $data = array();
public function __call($method, array $args) {
if (0 === strpos($method, 'get')) {
return $this->data[strtolower(substr($method, 3))];
}
throw new \LogicException(sprintf('Unsupported method: %s', $method));
}
}
/**
* If this class knows which fields exist, you can specify the methods here:
*
* @method string getName()
*/
class SomeClass extends ParentClass { }
![]() |
|||
899 | $rs = $this->Execute($stmt, $inputarr); |
||
0 ignored issues
–
show
|
|||
900 | View Code Duplication | if (0 != $this->ErrorNo()) { |
|
0 ignored issues
–
show
The method
ErrorNo does not exist on object<Adodb> ? Since you implemented __call , maybe consider adding a @method annotation.
If you implement This is often the case, when class ParentClass {
private $data = array();
public function __call($method, array $args) {
if (0 === strpos($method, 'get')) {
return $this->data[strtolower(substr($method, 3))];
}
throw new \LogicException(sprintf('Unsupported method: %s', $method));
}
}
/**
* If this class knows which fields exist, you can specify the methods here:
*
* @method string getName()
*/
class SomeClass extends ParentClass { }
![]() This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
901 | // Log to error log file |
||
902 | error_log('ErrorNo: ' . $this->ErrorNo() |
||
0 ignored issues
–
show
The method
ErrorNo does not exist on object<Adodb> ? Since you implemented __call , maybe consider adding a @method annotation.
If you implement This is often the case, when class ParentClass {
private $data = array();
public function __call($method, array $args) {
if (0 === strpos($method, 'get')) {
return $this->data[strtolower(substr($method, 3))];
}
throw new \LogicException(sprintf('Unsupported method: %s', $method));
}
}
/**
* If this class knows which fields exist, you can specify the methods here:
*
* @method string getName()
*/
class SomeClass extends ParentClass { }
![]() |
|||
903 | . "\nErrorMsg: " . $this->ErrorMsg() |
||
0 ignored issues
–
show
The method
ErrorMsg does not exist on object<Adodb> ? Since you implemented __call , maybe consider adding a @method annotation.
If you implement This is often the case, when class ParentClass {
private $data = array();
public function __call($method, array $args) {
if (0 === strpos($method, 'get')) {
return $this->data[strtolower(substr($method, 3))];
}
throw new \LogicException(sprintf('Unsupported method: %s', $method));
}
}
/**
* If this class knows which fields exist, you can specify the methods here:
*
* @method string getName()
*/
class SomeClass extends ParentClass { }
![]() |
|||
904 | ); |
||
905 | $this->RollbackTrans(); |
||
0 ignored issues
–
show
The method
RollbackTrans does not exist on object<Adodb> ? Since you implemented __call , maybe consider adding a @method annotation.
If you implement This is often the case, when class ParentClass {
private $data = array();
public function __call($method, array $args) {
if (0 === strpos($method, 'get')) {
return $this->data[strtolower(substr($method, 3))];
}
throw new \LogicException(sprintf('Unsupported method: %s', $method));
}
}
/**
* If this class knows which fields exist, you can specify the methods here:
*
* @method string getName()
*/
class SomeClass extends ParentClass { }
![]() |
|||
906 | return -1; |
||
0 ignored issues
–
show
The return type of
return -1; (integer ) is incompatible with the return type documented by Adodb::PExecute of type object .
If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design. Let’s take a look at an example: class Author {
private $name;
public function __construct($name) {
$this->name = $name;
}
public function getName() {
return $this->name;
}
}
abstract class Post {
public function getAuthor() {
return 'Johannes';
}
}
class BlogPost extends Post {
public function getAuthor() {
return new Author('Johannes');
}
}
class ForumPost extends Post { /* ... */ }
function my_function(Post $post) {
echo strtoupper($post->getAuthor());
}
Our function ![]() |
|||
907 | } |
||
908 | $this->CommitTrans(); |
||
0 ignored issues
–
show
The method
CommitTrans does not exist on object<Adodb> ? Since you implemented __call , maybe consider adding a @method annotation.
If you implement This is often the case, when class ParentClass {
private $data = array();
public function __call($method, array $args) {
if (0 === strpos($method, 'get')) {
return $this->data[strtolower(substr($method, 3))];
}
throw new \LogicException(sprintf('Unsupported method: %s', $method));
}
}
/**
* If this class knows which fields exist, you can specify the methods here:
*
* @method string getName()
*/
class SomeClass extends ParentClass { }
![]() |
|||
909 | return $rs; |
||
910 | } // end of PExecute |
||
911 | |||
912 | |||
913 | /** |
||
914 | * Generate, prepare and exec SQL |
||
915 | * |
||
916 | * @param array $ar_sql Same as GenSql() |
||
917 | * @param array $inputarr Optional parameters in sql |
||
918 | * @return object |
||
919 | * @see GenSql() |
||
920 | */ |
||
921 | public function PExecuteGenSql ($ar_sql, $inputarr = false) { |
||
922 | return $this->PExecute($this->GenSqlPrepare($ar_sql), $inputarr); |
||
923 | } // end of func PExecuteGenSql |
||
924 | |||
925 | |||
926 | /** |
||
927 | * Smarty quote string in sql, by check columns type |
||
928 | * |
||
929 | * @param string $table |
||
930 | * @param string $column |
||
931 | * @param mixed $val |
||
932 | * @return string |
||
933 | */ |
||
934 | View Code Duplication | public function QuoteValue ($table, $column, $val) { |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
935 | $this->GetMetaColumn($table); |
||
936 | if (!isset($this->aMetaColumn[$table][$column]->type)) { |
||
937 | error_log("Column to quote not exists($table.$column).\n"); |
||
938 | // Return quoted value for safety |
||
939 | $val = stripslashes($val); |
||
940 | return $this->qstr($val, false); |
||
0 ignored issues
–
show
The method
qstr does not exist on object<Adodb> ? Since you implemented __call , maybe consider adding a @method annotation.
If you implement This is often the case, when class ParentClass {
private $data = array();
public function __call($method, array $args) {
if (0 === strpos($method, 'get')) {
return $this->data[strtolower(substr($method, 3))];
}
throw new \LogicException(sprintf('Unsupported method: %s', $method));
}
}
/**
* If this class knows which fields exist, you can specify the methods here:
*
* @method string getName()
*/
class SomeClass extends ParentClass { }
![]() |
|||
941 | } |
||
942 | |||
943 | //print_r($this->aMetaColumn[$table][$column]); |
||
944 | $type = $this->aMetaColumn[$table][$column]->type; |
||
945 | //var_dump($type); |
||
946 | if (in_array($type, array( |
||
947 | 'bigint', |
||
948 | 'bit', |
||
949 | 'decimal', |
||
950 | 'double', |
||
951 | 'float', |
||
952 | 'int', |
||
953 | 'intn', // Sybase - tinyint |
||
954 | 'mediumint', |
||
955 | 'numeric', |
||
956 | 'numericn', // Sybase - numeric |
||
957 | 'real', |
||
958 | 'smallint', |
||
959 | 'tinyint', |
||
960 | ))) |
||
961 | // Need not quote, output directly |
||
962 | return $val; |
||
963 | // Sybase timestamp |
||
964 | //elseif ($this->IsDbSybase() && 'varbinary' == $type && 'timestamp' == $column) |
||
965 | elseif ($this->IsDbSybase() && 'timestamp' == $type) |
||
966 | return '0x' . $val; |
||
967 | else { |
||
968 | // Need quote, use db's quote method |
||
969 | $val = stripslashes($val); |
||
970 | return $this->qstr($val, false); |
||
0 ignored issues
–
show
The method
qstr does not exist on object<Adodb> ? Since you implemented __call , maybe consider adding a @method annotation.
If you implement This is often the case, when class ParentClass {
private $data = array();
public function __call($method, array $args) {
if (0 === strpos($method, 'get')) {
return $this->data[strtolower(substr($method, 3))];
}
throw new \LogicException(sprintf('Unsupported method: %s', $method));
}
}
/**
* If this class knows which fields exist, you can specify the methods here:
*
* @method string getName()
*/
class SomeClass extends ParentClass { }
![]() |
|||
971 | } |
||
972 | } // end of func GenSqlQuote |
||
973 | |||
974 | |||
975 | /** |
||
976 | * If a table exists in db ? |
||
977 | * |
||
978 | * @param string $tbl |
||
979 | * @return boolean |
||
980 | */ |
||
981 | View Code Duplication | public function TblExists ($tbl) { |
|
0 ignored issues
–
show
This method seems to be duplicated in your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
982 | if ($this->IsDbSybase()) { |
||
983 | $sql = "select count(1) as c from sysobjects where name = '$tbl' and type = 'U'"; |
||
984 | $rs = $this->Execute($sql); |
||
0 ignored issues
–
show
|
|||
985 | return (0 != $rs->fields['c']); |
||
986 | } |
||
987 | elseif ($this->IsDbMysql()) { |
||
988 | $sql = "SHOW TABLES LIKE '$tbl'"; |
||
989 | $rs = $this->Execute($sql); |
||
0 ignored issues
–
show
|
|||
990 | return (0 != $rs->RowCount()); |
||
991 | } |
||
992 | else { |
||
993 | // :NOTICE: Un-tested method |
||
994 | $sql = "select 1 from $tbl"; |
||
995 | $rs = $this->Execute($sql); |
||
0 ignored issues
–
show
$rs 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 ![]() |
|||
996 | return (0 == $this->ErrorNo()); |
||
0 ignored issues
–
show
The method
ErrorNo does not exist on object<Adodb> ? Since you implemented __call , maybe consider adding a @method annotation.
If you implement This is often the case, when class ParentClass {
private $data = array();
public function __call($method, array $args) {
if (0 === strpos($method, 'get')) {
return $this->data[strtolower(substr($method, 3))];
}
throw new \LogicException(sprintf('Unsupported method: %s', $method));
}
}
/**
* If this class knows which fields exist, you can specify the methods here:
*
* @method string getName()
*/
class SomeClass extends ParentClass { }
![]() |
|||
997 | } |
||
998 | } // end of func TblExists |
||
999 | |||
1000 | |||
1001 | /** |
||
1002 | * Smart write data row(s) to table |
||
1003 | * |
||
1004 | * Will auto check row existence, and decide to use INSERT or UPDATE, |
||
1005 | * so PRIMARY KEY column must include in $data array. |
||
1006 | * Also, table must have primary key defined. |
||
1007 | * @param string $tbl Table which rows to write to |
||
1008 | * @param array $data Row(s) data, only one row(1-dim array, index is column name) |
||
1009 | * or some rows(2-dim array, index layer 1 MUST be number and |
||
1010 | * will not write to db). |
||
1011 | * @param string $mode A auto detect/U update/I insert, ignore case. |
||
1012 | * If you assign some rows, it's better not to set this to 0, |
||
1013 | * because it will only detect by the FIRST row data. |
||
1014 | * @return int Number of inserted or updated rows, -1 means some error, |
||
1015 | * 0 and upper are normal result. |
||
1016 | */ |
||
1017 | public function Write ($tbl, $data, $mode = 'A') { |
||
1018 | // Find primary key column first |
||
1019 | $pk = $this->GetMetaPrimaryKey($tbl); |
||
1020 | |||
1021 | // Convert single row data to multi row mode |
||
1022 | if (!isset($data[0])) |
||
1023 | $data = array(0 => $data); |
||
1024 | // Convert primary key to array if it's single string now |
||
1025 | if (!is_array($pk)) |
||
1026 | $pk = array(0 => $pk); |
||
1027 | |||
1028 | // Columns in $data |
||
1029 | $ar_cols = array_keys($data[0]); |
||
1030 | // Check if primary key is assigned in $data |
||
1031 | $b_data_ok = true; |
||
1032 | foreach ($pk as $key) |
||
1033 | if (!in_array($key, $ar_cols)) |
||
1034 | $b_data_ok = false; |
||
1035 | // If no primary key column in $data, return -1 |
||
1036 | if (false == $b_data_ok) |
||
0 ignored issues
–
show
|
|||
1037 | return -1; |
||
1038 | |||
1039 | $mode = strtoupper($mode); |
||
1040 | // Consider mode if user not assigned |
||
1041 | View Code Duplication | if ('A' == $mode) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
1042 | $s_where = ' WHERE '; |
||
1043 | foreach ($pk as $key) |
||
1044 | $s_where .= " $key = " . $this->QuoteValue($tbl, $key, $data[0][$key]) |
||
1045 | . ' AND '; |
||
1046 | $s_where = substr($s_where, 0, strlen($s_where) - 5); |
||
1047 | if (0 < $this->GetRowCount($tbl, $s_where)) |
||
1048 | $mode = 'U'; |
||
1049 | else |
||
1050 | $mode = 'I'; |
||
1051 | } |
||
1052 | |||
1053 | // Do batch update or insert, prepare stmt first |
||
1054 | $sql = ''; |
||
0 ignored issues
–
show
$sql 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 ![]() |
|||
1055 | View Code Duplication | if ('U' == $mode) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
1056 | $ar_conf = array( |
||
1057 | 'UPDATE' => $tbl, |
||
1058 | 'LIMIT' => 1, |
||
1059 | ); |
||
1060 | foreach ($pk as $key) { |
||
1061 | // Primary key need remove from 'SET' clause |
||
1062 | // Actual value will assign later, do quote then. |
||
1063 | // :NOTICE: Remember to put pk data to end of row data when assign, |
||
1064 | // because where clause is after set clause. |
||
1065 | $ar_conf['WHERE'][] = "$key = " |
||
1066 | . $this->Param($key); |
||
0 ignored issues
–
show
The method
Param does not exist on object<Adodb> ? Since you implemented __call , maybe consider adding a @method annotation.
If you implement This is often the case, when class ParentClass {
private $data = array();
public function __call($method, array $args) {
if (0 === strpos($method, 'get')) {
return $this->data[strtolower(substr($method, 3))];
}
throw new \LogicException(sprintf('Unsupported method: %s', $method));
}
}
/**
* If this class knows which fields exist, you can specify the methods here:
*
* @method string getName()
*/
class SomeClass extends ParentClass { }
![]() |
|||
1067 | unset($ar_cols[array_search($key, $ar_cols)]); |
||
1068 | } |
||
1069 | // Convert array $ar_cols with to prepare param |
||
1070 | $ar_set = array(); |
||
1071 | foreach ($ar_cols as $key) |
||
1072 | $ar_set[$key] = $this->Param($key); |
||
0 ignored issues
–
show
The method
Param does not exist on object<Adodb> ? Since you implemented __call , maybe consider adding a @method annotation.
If you implement This is often the case, when class ParentClass {
private $data = array();
public function __call($method, array $args) {
if (0 === strpos($method, 'get')) {
return $this->data[strtolower(substr($method, 3))];
}
throw new \LogicException(sprintf('Unsupported method: %s', $method));
}
}
/**
* If this class knows which fields exist, you can specify the methods here:
*
* @method string getName()
*/
class SomeClass extends ParentClass { }
![]() |
|||
1073 | // Fin, assign 'SET' clause |
||
1074 | $ar_conf['SET'] = $ar_set; |
||
1075 | } |
||
1076 | elseif ('I' == $mode) { |
||
1077 | $ar_set = array(); |
||
1078 | foreach ($ar_cols as $key) { |
||
1079 | $ar_set[$key] = $this->Param($key); |
||
0 ignored issues
–
show
The method
Param does not exist on object<Adodb> ? Since you implemented __call , maybe consider adding a @method annotation.
If you implement This is often the case, when class ParentClass {
private $data = array();
public function __call($method, array $args) {
if (0 === strpos($method, 'get')) {
return $this->data[strtolower(substr($method, 3))];
}
throw new \LogicException(sprintf('Unsupported method: %s', $method));
}
}
/**
* If this class knows which fields exist, you can specify the methods here:
*
* @method string getName()
*/
class SomeClass extends ParentClass { }
![]() |
|||
1080 | } |
||
1081 | $ar_conf = array( |
||
1082 | 'INSERT' => $tbl, |
||
1083 | 'VALUES' => $ar_set, |
||
1084 | ); |
||
1085 | } |
||
1086 | $sql = $this->GenSqlPrepare($ar_conf); |
||
0 ignored issues
–
show
The variable
$ar_conf 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
![]() |
|||
1087 | |||
1088 | /* Treat moved to SqlGenerator |
||
1089 | //$sql = $this->GenSql($ar_conf); |
||
1090 | // Remove duplicate ' in sql add by SqlGenerator, |
||
1091 | // Execute after Prepare will auto recoginize variant type and quote, |
||
1092 | // but notice, it's VAR TYPE and NOT DB COLUMN TYPE. |
||
1093 | // replaceQuote: The string used to escape quotes. Eg. double single-quotes for |
||
1094 | // Microsoft SQL, and backslash-quote for MySQL. Used by qstr. |
||
1095 | if ("''" == $this->replaceQuote) |
||
1096 | $s_quote = "'"; |
||
1097 | else |
||
1098 | $s_quote = $this->replaceQuote; |
||
1099 | $sql = preg_replace( |
||
1100 | "/ {$s_quote}([\?\:\w\-_]+){$s_quote}([, ])/i", |
||
1101 | " $1$2", $sql); |
||
1102 | */ |
||
1103 | |||
1104 | if (!empty($sql)) { |
||
1105 | // Do prepare |
||
1106 | $stmt = $this->Prepare($sql); |
||
0 ignored issues
–
show
|
|||
1107 | // Execute |
||
1108 | View Code Duplication | if ('U' == $mode) { |
|
0 ignored issues
–
show
This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
1109 | foreach ($data as &$row) { |
||
1110 | // Change pk's value position when update mode |
||
1111 | foreach ($pk as $key) { |
||
1112 | $v = $row[$key]; |
||
1113 | unset($row[$key]); |
||
1114 | $row[$key] = $v; |
||
1115 | } |
||
1116 | } |
||
1117 | unset($row); |
||
1118 | } |
||
1119 | // Now, finanly, actual write data |
||
1120 | // Auto convert encoding ? |
||
1121 | // Use of prepare we must convert $data manually, because $data is not sql. |
||
1122 | $this->EncodingConvert($data); |
||
1123 | try { |
||
1124 | $this->Execute($stmt, $data); |
||
0 ignored issues
–
show
|
|||
1125 | } |
||
1126 | catch (Exception $e) { |
||
1127 | // Show error message ? |
||
1128 | $this->RollbackTrans(); |
||
0 ignored issues
–
show
The method
RollbackTrans does not exist on object<Adodb> ? Since you implemented __call , maybe consider adding a @method annotation.
If you implement This is often the case, when class ParentClass {
private $data = array();
public function __call($method, array $args) {
if (0 === strpos($method, 'get')) {
return $this->data[strtolower(substr($method, 3))];
}
throw new \LogicException(sprintf('Unsupported method: %s', $method));
}
}
/**
* If this class knows which fields exist, you can specify the methods here:
*
* @method string getName()
*/
class SomeClass extends ParentClass { }
![]() |
|||
1129 | return -1; |
||
1130 | } |
||
1131 | // Any error ? |
||
1132 | View Code Duplication | if (0 != $this->ErrorNo()) { |
|
0 ignored issues
–
show
The method
ErrorNo does not exist on object<Adodb> ? Since you implemented __call , maybe consider adding a @method annotation.
If you implement This is often the case, when class ParentClass {
private $data = array();
public function __call($method, array $args) {
if (0 === strpos($method, 'get')) {
return $this->data[strtolower(substr($method, 3))];
}
throw new \LogicException(sprintf('Unsupported method: %s', $method));
}
}
/**
* If this class knows which fields exist, you can specify the methods here:
*
* @method string getName()
*/
class SomeClass extends ParentClass { }
![]() This code seems to be duplicated across your project.
Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation. You can also find more detailed suggestions in the “Code” section of your repository. ![]() |
|||
1133 | // Log to error log file |
||
1134 | error_log('ErrorNo: ' . $this->ErrorNo() |
||
0 ignored issues
–
show
The method
ErrorNo does not exist on object<Adodb> ? Since you implemented __call , maybe consider adding a @method annotation.
If you implement This is often the case, when class ParentClass {
private $data = array();
public function __call($method, array $args) {
if (0 === strpos($method, 'get')) {
return $this->data[strtolower(substr($method, 3))];
}
throw new \LogicException(sprintf('Unsupported method: %s', $method));
}
}
/**
* If this class knows which fields exist, you can specify the methods here:
*
* @method string getName()
*/
class SomeClass extends ParentClass { }
![]() |
|||
1135 | . "\nErrorMsg: " . $this->ErrorMsg() |
||
0 ignored issues
–
show
The method
ErrorMsg does not exist on object<Adodb> ? Since you implemented __call , maybe consider adding a @method annotation.
If you implement This is often the case, when class ParentClass {
private $data = array();
public function __call($method, array $args) {
if (0 === strpos($method, 'get')) {
return $this->data[strtolower(substr($method, 3))];
}
throw new \LogicException(sprintf('Unsupported method: %s', $method));
}
}
/**
* If this class knows which fields exist, you can specify the methods here:
*
* @method string getName()
*/
class SomeClass extends ParentClass { }
![]() |
|||
1136 | ); |
||
1137 | $this->RollbackTrans(); |
||
0 ignored issues
–
show
The method
RollbackTrans does not exist on object<Adodb> ? Since you implemented __call , maybe consider adding a @method annotation.
If you implement This is often the case, when class ParentClass {
private $data = array();
public function __call($method, array $args) {
if (0 === strpos($method, 'get')) {
return $this->data[strtolower(substr($method, 3))];
}
throw new \LogicException(sprintf('Unsupported method: %s', $method));
}
}
/**
* If this class knows which fields exist, you can specify the methods here:
*
* @method string getName()
*/
class SomeClass extends ParentClass { }
![]() |
|||
1138 | return -1; |
||
1139 | } |
||
1140 | else { |
||
1141 | $this->CommitTrans(); |
||
0 ignored issues
–
show
The method
CommitTrans does not exist on object<Adodb> ? Since you implemented __call , maybe consider adding a @method annotation.
If you implement This is often the case, when class ParentClass {
private $data = array();
public function __call($method, array $args) {
if (0 === strpos($method, 'get')) {
return $this->data[strtolower(substr($method, 3))];
}
throw new \LogicException(sprintf('Unsupported method: %s', $method));
}
}
/**
* If this class knows which fields exist, you can specify the methods here:
*
* @method string getName()
*/
class SomeClass extends ParentClass { }
![]() |
|||
1142 | return count($data); |
||
1143 | } |
||
1144 | } |
||
1145 | else |
||
1146 | return -1; |
||
1147 | } // end of func Write |
||
1148 | |||
1149 | |||
1150 | } // end of class Adodb |
||
1151 | ?> |
||
0 ignored issues
–
show
It is not recommended to use PHP's closing tag
?> in files other than templates.
Using a closing tag in PHP files that only contain PHP code is not recommended as you might accidentally add whitespace after the closing tag which would then be output by PHP. This can cause severe problems, for example headers cannot be sent anymore. A simple precaution is to leave off the closing tag as it is not required, and it also has no negative effects whatsoever. ![]() |
|||
1152 |
This class, trait or interface has been deprecated. The supplier of the file has supplied an explanatory message.
The explanatory message should give you some clue as to whether and when the type will be removed from the class and what other constant to use instead.