添加后台代理代码

This commit is contained in:
2026-03-15 01:27:05 +08:00
parent 11f9ac4dc1
commit ea08c9366a
5254 changed files with 721042 additions and 0 deletions

View File

@@ -0,0 +1,469 @@
<?php
/**
* $Id: impls.php 401 2015-11-06 08:28:26Z dong.chen $
* @author caoym(caoyangmin@gmail.com)
*/
namespace phprs\ezsql\impls;
use phprs\util\NestedStringCut;
use phprs\util\Verify;
use phprs\ezsql\SqlConetxt;
class Response{
public function __construct($success,$pdo, $st){
$this->pdo = $pdo;
$this->st = $st;
$this->success = $success;
$this->rows = $this->st->rowCount();
}
public function lastInsertId($name=null){
return $this->pdo->lastInsertId($name);
}
/**
* @var bool
* true on success or false on failure.
*/
public $success;
/**
* @var int
* the number of rows.
*/
public $rows;
/**
*
* @var \PDO
*/
public $pdo;
/**
* @var \PDOStatement
*/
public $st;
}
class SelectImpl
{
static public function select($context, $columns){
$context->appendSql("SELECT $columns");
}
}
class FromImpl
{
static public function from($context, $tables){
$context->appendSql("FROM $tables");
}
}
class DeleteImpl
{
static public function deleteFrom($context, $from)
{
$context->appendSql("DELETE FROM $from");
}
}
class JoinImpl
{
static public function join($context, $type, $table) {
if($type){
$context->appendSql("$type JOIN $table");
}else{
$context->appendSql("JOIN $table");
}
}
}
class JoinOnImpl
{
static public function on($context, $condition) {
$context->appendSql("ON $condition");
}
}
class ForUpdateImpl
{
static public function forUpdate($context){
$context->appendSql("FOR UPDATE");
}
}
class ForUpdateOfImpl
{
static public function of($context, $column){
$context->appendSql("OF $column");
}
}
class InsertImpl
{
static public function insertInto($context, $table) {
$context->appendSql("INSERT INTO $table");
}
}
class ReplaceImpl
{
static public function replaceInto($context, $table) {
$context->appendSql("REPLACE INTO $table");
}
}
class ValuesImpl
{
static public function values($context, $values){
$params = [];
$stubs = [];
foreach ($values as $v){
if(is_a($v, 'phprs\\ezsql\\Native')){//直接拼接sql不需要转义
$stubs[]=$v->get();
}else{
$stubs[]='?';
$params[] = $v;
}
}
$stubs = implode(',', $stubs);
if(array_keys($values) === range(0, count($values) - 1)){
//VALUES(val0, val1, val2)
$context->appendSql("VALUES($stubs)");
}else{
//(col0, col1, col2) VALUES(val0, val1, val2)
$columns = implode(',', array_keys($values));
$context->appendSql("($columns) VALUES($stubs)",false);
}
$context->appendParams($params);
}
private $sql = null;
}
class UpdateImpl
{
static public function update($context, $table){
$context->appendSql("UPDATE $table");
}
}
class UpdateSetImpl
{
public function set($context, $column, $value){
$prefix = '';
if($this->first){
$this->first = false;
$prefix = 'SET ';
}else{
$prefix = ',';
}
if(is_a($value, 'phprs\\ezsql\\Native')){
$context->appendSql("$prefix$column=$value",$prefix == 'SET ');
}else{
$context->appendSql("$prefix$column=?",$prefix == 'SET ');
$context->appendParams([$value]);
}
}
public function setArgs($context, $values){
$set = [];
$params = [];
foreach ($values as $k=>$v){
if(is_a($v, 'phprs\\ezsql\\Native')){//直接拼接sql不需要转义
$set[]= "$k=".$v->get();
}else{
$set[]= "$k=?";
$params[]=$v;
}
}
if($this->first){
$this->first = false;
$context->appendSql('SET '.implode(',', $set));
$context->appendParams($params);
}else{
$context->appendSql(','.implode(',', $set),false);
$context->appendParams($params);
}
}
private $first=true;
}
class OrderByImpl
{
public function orderByArgs($context, $orders){
if(empty($orders)){
return $this;
}
$params = array();
foreach ($orders as $k=>$v){
if(is_integer($k)){
Verify::isTrue(
preg_match('/^[a-zA-Z0-9_.]+$/', $v),
new \InvalidArgumentException("invalid params for orderBy(".json_encode($orders).")"));
$params[] = $v;
}else{
$v = strtoupper($v);
Verify::isTrue(
preg_match('/^[a-zA-Z0-9_.]+$/', $k) &&
($v =='DESC' || $v =='ASC'), new \InvalidArgumentException("invalid params for orderBy(".json_encode($orders).")"));
$params[] = "$k $v";
}
}
if($this->first){
$this->first = false;
$context->appendSql('ORDER BY '.implode(',', $params));
}else{
$context->appendSql(','.implode(',', $params),false);
}
return $this;
}
public function orderBy($context, $column, $order=null){
if($this->first){
$this->first = false;
$context->appendSql("ORDER BY $column");
}else{
$context->appendSql(",$column", false);
}
if($order){
$context->appendSql($order);
}
return $this;
}
private $first=true;
}
class LimitImpl
{
static public function limit($context, $size){
$intSize = intval($size);
Verify::isTrue(strval($intSize) == $size,
new \InvalidArgumentException("invalid params for limit($size)"));
$context->appendSql("LIMIT $size");
}
static public function limitWithOffset($context,$start, $size){
$intStart = intval($start);
$intSize = intval($size);
Verify::isTrue(strval($intStart) == $start && strval($intSize) == $size,
new \InvalidArgumentException("invalid params for limit($start, $size)"));
$context->appendSql("LIMIT $start,$size");
}
}
class WhereImpl{
static private function findQ($str,$offset = 0,$no=0){
$found = strpos($str, '?', $offset);
if($no == 0 || $found === false){
return $found;
}
return self::findQ($str, $found+1, $no-1);
}
static public function having($context, $expr, $args){
self::condition($context, 'HAVING', $expr, $args);
}
static public function where($context, $expr, $args){
self::condition($context, 'WHERE', $expr, $args);
}
static public function havingArgs($context, $args){
self::conditionArgs($context, 'HAVING', $args);
}
static public function whereArgs($context, $args){
self::conditionArgs($context, 'WHERE', $args);
}
/**
* find like Mongodb query glossary
* whereArray(
* [
* 'id'=>['>'=>1],
* 'name'=>'cym',
* ]
* )
* 支持的操作符有
* = 'id'=>['=' => 1]
* > 'id'=>['>' => 1]
* < 'id'=>['<' => 1]
* <> 'id'=>['<>' => 1]
* >= 'id'=>['>=' => 1]
* <= 'id'=>['<=' => 1]
* BETWEEN 'id'=>['BETWEEN' => [1 ,2]]
* LIKE 'id'=>['LIKE' => '1%']
* IN 'id'=>['IN' => [1,2,3]]
* NOT IN 'id'=>['NOT IN' => [1,2,3]]
*
* @param array $args
*/
static public function conditionArgs($context, $prefix, $args=[]){
if($args ===null){
return ;
}
$exprs = array();
$params = array();
foreach ($args as $k => $v){
if(is_array($v)){
$ops = ['=', '>', '<', '<>', '>=', '<=', 'IN', 'NOT IN', 'BETWEEN', 'LIKE'];
$op = array_keys($v)[0];
$op = strtoupper($op);
Verify::isTrue(
false !== array_search($op, $ops),
new \InvalidArgumentException("invalid param $op for whereArgs"));
$var = array_values($v)[0];
if($op == 'IN' || $op == 'NOT IN'){
$stubs = [];
foreach ($var as $i){
if(is_a($i, 'phprs\\ezsql\\Native')){
$stubs[]=strval($i);
}else{
$stubs[]='?';
$params[] = $i;
}
}
$stubs = implode(',', $stubs);
$exprs[] = "$k $op ($stubs)";
}else if($op == 'BETWEEN'){
$cond = "$k BETWEEN";
if(is_a($var[0], 'phprs\\ezsql\\Native')){
$cond = "$cond ".strval($var[0]);
}else{
$cond = "$cond ?";
$params[] = $var[0];
}
if(is_a($var[1], 'phprs\\ezsql\\Native')){
$cond = "$cond AND ".strval($var[1]);
}else{
$cond = "$cond AND ?";
$params[] = $var[1];
}
$exprs[] = $cond;
}else{
if(is_a($var, 'phprs\\ezsql\\Native')){
$exprs[] = "$k $op ".strval($var);
}else{
$exprs[] = "$k $op ?";
$params[] = $var;
}
}
}else{
if(is_a($v, 'phprs\\ezsql\\Native')){
$exprs[] = "$k = ".strval($v);
}else{
$exprs[] = "$k = ?";
$params[] = $v;
}
}
}
return self::condition($context, $prefix, implode(' AND ', $exprs), $params);
}
static public function condition($context, $prefix, $expr, $args){
if(!empty($expr)){
if($args){
//因为PDO不支持绑定数组变量, 这里需要手动展开数组
//也就是说把 where("id IN(?)", [1,2]) 展开成 where("id IN(?,?)", 1,2)
$cutted = null;
$cut = null;
$toReplace = array();
$newArgs=array();
//找到所有数组对应的?符位置
foreach ($args as $k =>$arg){
if(is_array($arg) || is_a($arg, 'phprs\\ezsql\\Native')){
if(!$cutted){
$cut = new NestedStringCut($expr);
$cutted = $cut->getText();
}
//找到第$k个?符
$pos = self::findQ($cutted, 0, $k);
$pos = $cut->mapPos($pos);
Verify::isTrue($pos !== false,
new \InvalidArgumentException("unmatched params and ? @ $expr"));
if(is_array($arg)){
$stubs = [];
foreach ($arg as $i){
if(is_a($i, 'phprs\\ezsql\\Native')){
$stubs[] = strval($i);
}else{
$stubs[] = '?';
$newArgs[] = $i;
}
}
$stubs = implode(',', $stubs);
}else{
$stubs = strval($arg);
}
$toReplace[] = [$pos, $stubs];
}else{
$newArgs[]=$arg;
}
}
if(count($toReplace)){
$toReplace = array_reverse($toReplace);
foreach ($toReplace as $i){
list($pos, $v) = $i;
$expr = substr($expr, 0, $pos).$v. substr($expr, $pos+1);
}
$args = $newArgs;
}
}
$context->appendSql($prefix.' '.$expr);
if($args){
$context->appendParams($args);
}
}
}
}
class GroupByImpl{
static public function groupBy($context, $column){
$context->appendSql("GROUP BY $column");
}
}
class ExecImpl
{
/**
*
* @param $context SqlConetxt
* @param $db \PDO
* @param $exceOnError boolean whether throw exceptions
* @return Response
*/
static public function exec($context, $db, $exceOnError=true) {
if($exceOnError){
$db->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
}
$st = $db->prepare($context->sql);
$success = $st->execute($context->params);
return new Response($success, $db,$st);
}
/**
*
* @param SqlConetxt $context
* @param PDO $db
* @param boolean $errExce
* @param string $asDict return as dict or array
* @return false|array
*/
static public function get($context, $db, $dictAs=null ,$errExce=true){
if($errExce){
$db->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
}
$st = $db->prepare($context->sql);
if($st->execute($context->params)){
$res = $st->fetchAll(\PDO::FETCH_ASSOC);
if ($dictAs){
$dict= [];
foreach ($res as $i){
$dict[$i[$dictAs]]=$i;
}
return $dict;
}
return $res;
}else{
return false;
}
}
}