I am preparing a simple class. I want to create a query by following a different path. Class below it is a draft. I look forward to your suggestions.
The Cyclomatic Complexity number 4. PHP Mess Detector, PHPCS fixer tools, I have no problems.
My English is not good, I'm sorry.
<?php
class test
{
protected $q = array();
protected $p = array();
public function get()
{
$new = array();
foreach ($this->p as $value) {
$new = array_merge($new, $value);
}
$this->p = $new;
print_r($this->p);
$query = 'select * from table ';
foreach ($this->q as $sql) {
$query .= implode(' ', $sql) . ' ';
}
echo $query . PHP_EOL;
}
public function camelCase($value)
{
return strtolower(preg_replace('/(.)([A-Z])/', '$1 $2', $value));
}
public function __call($method, $params)
{
$clause = $this->camelCase($method);
$clause = explode(' ', $clause);
if ($key = array_search('in', $clause)) {
$clause[$key] = 'in(?)';
} elseif (isset($clause[2]) && in_array($clause[2], array(
'or',
'and'
))) {
$clause[1] = $clause[1] . ' =?';
$clause[3] = $clause[3] . ' =?';
} elseif (isset($clause[0]) && $clause[0] == 'limit') {
$clause[$key] = 'limit ? offset ?';
} elseif (isset($clause[1]) && $clause[1] != 'by') {
$clause[1] = $clause[1] . ' =?';
}
$this->q[] = $clause;
$this->p[] = $params;
return $this;
}
}
The use of the query creator class is as follows.
<?php
(new test())
->orderByIdDesc()
->limit(15)
->get();
(new test())
->whereIdOrName(6,'foo')
->get();
(new test())
->whereIdIsNotNull(10)
->get();
(new test())
->whereIdIn(9)
->get();
(new test())
->whereIdNotIn(8)
->get();
Output:
Array
(
[0] => 15
)
select * from table order by id desc limit ? offset ?
Array
(
[0] => 6
[1] => foo
)
select * from table where id =? or name =?
Array
(
[0] => 10
)
select * from table where id =? is not null
Array
(
[0] => 9
)
select * from table where id in(?)
Array
(
[0] => 8
)
select * from table where id not in(?)
If it does not make sense, you can write why it doesn't make sense.
In terms of responsibility, your class should never echo in a method.
public function get()
{
$new = array();
foreach ($this->p as $value) {
$new = array_merge($new, $value);
}
$this->p = $new;
print_r($this->p);
$query = 'select * from table ';
foreach($this->q as $sql){
$query .= implode(' ', $sql) . ' ';
}
return $query . PHP_EOL;
}
And
<?= (new test())
->orderByIdDesc()
->limit(15)
->get();
Also, you should have a look at existing libraries rather than inventing and maintaining your own (eloquent for instance).
If you're PHP 5.4+ (which I hope), you could use the short array syntax.
The class could probably be final and with private attributes.