vendor/lm/db/src/SqlService.php line 152

Open in your IDE?
  1. <?php
  2. /**
  3.  * @version EC-CUBE4系
  4.  * @copyright 株式会社 翔 kakeru.co.jp
  5.  *
  6.  * 2021年12月05日作成
  7.  *
  8.  * app\Customize\Service\SqlService.php
  9.  *
  10.  * SQL文を作成する
  11.  *
  12.  * このクラスを変更する場合は株式会社 翔の許可を取ってください
  13.  * 2021/12/07修正 WHERE句 AS句 スペースを修正
  14.  * 2021/12/07 AS句 スペースを修正
  15.  * 2022/08/18 IN区 パラメーター化
  16.  *
  17.  *                                        ≡≡≡┏(^o^)┛
  18.  *****************************************************/
  19. namespace Lm\Service\Db;
  20. use Lm\Service\Cache\CacheService;
  21. use Lm\Service\Cache\LmCacheTrait;
  22. class SqlService
  23. {
  24.     use LmCacheTrait {
  25.         LmCacheTrait::__construct as __traitConstruct;
  26.     }
  27.     const READ true;
  28.     const WRITE false;
  29.     const AS_SYMBOL 'T'#Tableの簡略化名 AS句
  30.     const AS_PATAN '/^[T0-9]+\./';
  31.     #初期値
  32.     const DEF '';
  33.     #戻り値
  34.     const RE null;
  35.     const SELECT self::AS_SYMBOL '.* ';
  36.     const ParamKIgo ':P_';
  37.     protected static $_Connect = [];
  38.     #DB接続
  39.     protected $Connect#Object;
  40.     protected $Stmt#object
  41.     protected $Table_;
  42.     protected $Select_ '';
  43.     protected $Selects_ = [];
  44.     protected $Set_ = [];
  45.     protected $Sql_;
  46.     protected $Values_ = [];
  47.     protected $Where_ = [];
  48.     protected $WhereLogical = [];
  49.     protected $Param_ = [];
  50.     protected $Order_ = [];
  51.     protected $OrderBy_;
  52.     protected $Join_ = [];
  53.     protected $Limit_;
  54.     protected $OffSet_;
  55.     protected $Group_;
  56.     protected $ConName;
  57.     protected $Num 0;
  58.     protected $ForeignKey_ 1;
  59.     protected $Column_ = [];
  60.     #SQl分をエコーで表示する パラメーターは配列
  61.     protected $ViewFlg;
  62.     /**
  63.      * コンストラクト
  64.      * DBの接続
  65.      */
  66.     function __construct()
  67.     {
  68.         $cacheService = new CacheService();
  69.         //
  70.         $this->__traitConstruct($cacheService);
  71.         //
  72.         $this->Connect $this->ConnectDB(false);
  73.     }
  74.     function ConnectDB($forceReconnect false)
  75.     {
  76.         if ($forceReconnect || empty(self::$_Connect)) {
  77.             $dbManagerRead = new DbManager([], self::READ);
  78.             $dbManagerWrite = new DbManager([], self::WRITE);
  79.             self::$_Connect[self::READ] = $dbManagerRead->get();
  80.             self::$_Connect[self::WRITE] = $dbManagerWrite->get();
  81.             return self::$_Connect;
  82.         } else {
  83.             return self::$_Connect;
  84.         }
  85.     }
  86.     /**
  87.      * 初期化
  88.      * SQL 発行後変数の初期化します
  89.      */
  90.     protected function Initialize()
  91.     {
  92.         $this->Table_ null;
  93.         $this->Select_ '';
  94.         $this->Selects_ = [];
  95.         $this->Set_ = [];
  96.         $this->Where_ = [];
  97.         $this->WhereLogical = [];
  98.         $this->Param_ = [];
  99.         $this->Order_ = [];
  100.         $this->OrderBy_ = [];
  101.         $this->Join_ = [];
  102.         $this->Limit_ null;
  103.         $this->OffSet_ null;
  104.         $this->Group_ null;
  105.         $this->Values_ = [];
  106.         $this->Sql_ null;
  107.         $this->Num 0;
  108.         $this->ViewFlg false;
  109.         $this->Stmt null;
  110.         $this->Column_ = [];
  111.         if (== $this->ForeignKey_) {
  112.             $this->ForeignKey_ 1;
  113.         }
  114.         $this->ForeignKey_ null;
  115.     }
  116.     /**
  117.      * getter
  118.      *
  119.      * @return string
  120.      */
  121.     public function getSql()
  122.     {
  123.         return $this->Sql_;
  124.     }
  125.     /**
  126.      * シングルの連想配列を返す
  127.      * @param int $ViewFlg $ViewFlg 1 #SQl分をエコーで表示する パラメーターは配列 2 exit 付き
  128.      *
  129.      * @return array 無ければ NULLを返す
  130.      */
  131.     public function Find($ViewFlg 0)
  132.     {
  133.         $this->ViewFlg $ViewFlg;
  134.         #Select分 の作成
  135.         $this->MakeSelect();
  136.         $Value $this->Fetch();
  137.         return $Value $Value self::RE;
  138.     }
  139.     /**
  140.      * リストとして連想配列で返す
  141.      * @param int|bool $Flg $ViewFlg 1 #SQl分をエコーで表示する パラメーターは配列 2 exit 付き
  142.      *
  143.      * @return array 無ければ NULLを返す
  144.      */
  145.     public function FindAll($Flg false)
  146.     {
  147.         #Select分 の作成
  148.         $this->MakeSelect();
  149.         return $this->FetchAll($Flg);
  150.     }
  151.     /**
  152.      * リストとして連想配列で返す
  153.      * @param int|bool $Flg 1 #SQl分をエコーで表示する パラメーターは配列 2 exit 付き
  154.      *
  155.      * @return array 無ければ  配列を返す
  156.      */
  157.     public function FindArr($Flg false)
  158.     {
  159.         $Re $this->FindAll($Flg);
  160.         return $Re == self::RE ? [] : $Re;
  161.     }
  162.     /**
  163.      * SQL文を実行し想配列で返す
  164.      * @param int|bool $Flg 1 #SQl分をエコーで表示する パラメーターは配列 2 exit 付き
  165.      *
  166.      * @return array 無ければ  NULLを返す
  167.      */
  168.     public function Finds($Flg false)
  169.     {
  170.         $this->ViewFlg $Flg;
  171.         #Select分 の作成
  172.         $this->MakeSelect();
  173.         return $this->FetchAll($Flg);
  174.     }
  175.     /**
  176.      * 最大値を返すリ
  177.      *
  178.      * @param int|bool $Flg
  179.      * @param string $Column
  180.      * @return int
  181.      */
  182.     public function Max($Flg false$Column null)
  183.     {
  184.         if (!$Column = isset($Column) ? $Column : (isset($this->Column_[0]) ? $this->Column_[0] : '')) {
  185.             return 0;
  186.         }
  187.         $this->Select_ "MAX(" self::SetAs($Column) . ') AS Value';
  188.         $this->Column_ = [];
  189.         #Select分 の作成
  190.         $Max $this->Find($Flg);
  191.         return isset($Max['Value']) ? $Max['Value'] : 0;
  192.     }
  193.     /**
  194.      * 最小値値を返すリ
  195.      *
  196.      * @param int|bool $Flg
  197.      * @param string $Column
  198.      * @return int
  199.      */
  200.     public function Min($Flg false$Column null)
  201.     {
  202.         if (!$Column = isset($Column) ? $Column : (isset($this->Column_[0]) ? $this->Column_[0] : '')) {
  203.             return 0;
  204.         }
  205.         $this->Select_ "MIN(" self::SetAs($Column) . ') AS Value';
  206.         $this->Column_ = [];
  207.         #Select分 の作成
  208.         $Min $this->Find($Flg);
  209.         return isset($Min['Value']) ? $Min['Value'] : 0;
  210.     }
  211.     /**
  212.      * カウントする
  213.      *
  214.      * @param int|bool $Flg
  215.      * @param string $Column
  216.      * @return int
  217.      */
  218.     public function Count($Flg false$Column null)
  219.     {
  220.         if (!$Column = isset($Column) ? $Column : (isset($this->Column_[0]) ? $this->Column_[0] : '')) {
  221.             $this->Select_ "COUNT(*) AS Value";
  222.         } else {
  223.             $this->Select_ "Count(" self::SetAs($Column) . ') AS Value';
  224.         }
  225.         $this->Column_ = [];
  226.         $Count $this->Find($Flg);
  227.         return isset($Count['Value']) ? $Count['Value'] : 0;
  228.     }
  229.     /**
  230.      * UPDATE する
  231.      *
  232.      * @param int|bool $Flg
  233.      * @param array $Values
  234.      * @return bool|null
  235.      */
  236.     public function Update($Flg false$Values = [])
  237.     {
  238.         $this->ViewFlg $Flg;
  239.         if ($Values) {
  240.             $this->Values($Values);
  241.         }
  242.         #Update文の作成
  243.         $this->MakeUpdate();
  244.         return $this->Exec();
  245.     }
  246.     /**
  247.      * @param int|bool $Flg
  248.      * @param array $Values
  249.      * @param int $lastInsertId
  250.      * @return bool|null
  251.      */
  252.     public function Insert($Flg false$Values self::DEF, &$lastInsertId null)
  253.     {
  254.         $this->ViewFlg $Flg;
  255.         if ($Values) {
  256.             $this->Values($Values);
  257.         }
  258.         $this->MakeInsert();
  259.         if ($Num $this->Exec()) {
  260.             //
  261.             $lastInsertId $this->Connect[self::WRITE]->lastInsertId();
  262.         }
  263.         return $Num;
  264.     }
  265.     /**
  266.      * 2020/06/03
  267.      * 有ればUP 無ければINSERT
  268.      * @param int|bool $Flg
  269.      * @return bool|null
  270.      */
  271.     public function Inserts($Flg false)
  272.     {
  273.         $this->ViewFlg $Flg;
  274.         $this->MakeInserts();
  275.         return $this->Exec();
  276.     }
  277.     /**
  278.      * @param int|bool $Flg
  279.      * @return bool|null
  280.      */
  281.     public function Delete($Flg false)
  282.     {
  283.         $this->ViewFlg $Flg;
  284.         $this->MakeDelete();
  285.         return $this->Exec();
  286.     }
  287.     /**
  288.      * TRUNCATE DATA の初期化
  289.      *
  290.      * @param int|bool $Flg
  291.      * @return void
  292.      */
  293.     public function Truncate($Flg false)
  294.     {
  295.         if (!$this->Table_) {
  296.             return;
  297.         }
  298.         $this->ViewFlg $Flg;
  299.         $this->Sql_ 'TRUNCATE ' $this->Table_;
  300.         $this->Exec();
  301.         return;
  302.     }
  303.     /**
  304.      * ForeignKey
  305.      * 外部キーのチェックを無効にする
  306.      *
  307.      * @return $this
  308.      */
  309.     public function ForeignKey()
  310.     {
  311.         $this->ForeignKey_ 0;
  312.         return $this;
  313.     }
  314.     /**
  315.      * カラムの表示
  316.      *
  317.      * @param int|bool $Flg
  318.      * @return array|null
  319.      */
  320.     public function ShowColumns($Flg false)
  321.     {
  322.         $this->Sql_ "SHOW COLUMNS FROM {$this->Table_} ";
  323.         $Arr $this->FetchAll();
  324.         if (!$Flg) {
  325.             return $Arr;
  326.         }
  327.         foreach ($Arr as $i => $Val) {
  328.             $Re[$Val['Field']] = $Val;
  329.         }
  330.         return $Re;
  331.     }
  332.     /**
  333.      * テーブルの表示
  334.      *
  335.      * @param int|bool $Flg
  336.      * @return array|null
  337.      */
  338.     public function ShowTable($Flg false)
  339.     {
  340.         $this->Sql_ "SHOW TABLE STATUS";
  341.         $Arr $this->FetchAll();
  342.         if (!$Flg) {
  343.             return $Arr;
  344.         }
  345.         foreach ($Arr as $val) {
  346.             $Re[$val['Name']] = $val;
  347.         }
  348.         return $Re;
  349.     }
  350.     /**
  351.      * バージョンの表示
  352.      *
  353.      * @return mixed
  354.      */
  355.     public function VerSion()
  356.     {
  357.         $this->ConName;
  358.         $this->Sql_ 'select version()';
  359.         $Re $this->Fetch();
  360.         return $Re['version()'];
  361.     }
  362.     /**
  363.      * 自動採番の値の変更
  364.      *
  365.      * @param int $Num
  366.      * @return bool|null
  367.      */
  368.     public function Auto_Num($Num 1)
  369.     {
  370.         $this->Sql_ "ALTER TABLE {$this->Table_} AUTO_INCREMENT={$Num}";
  371.         return $this->Exec();
  372.     }
  373.     /**
  374.      * テーブルのの定義
  375.      *
  376.      * @param string $Table
  377.      * @return $this
  378.      */
  379.     public function Table($Table)
  380.     {
  381.         $this->Table_ $Table;
  382.         return $this;
  383.     }
  384.     /**
  385.      * SELECTの定義
  386.      *
  387.      * @param string Select
  388.      * @return $this
  389.      */
  390.     public function Select($Select '')
  391.     {
  392.         if (!$Select) {
  393.             return $this;
  394.         }
  395.         $this->Select_ $Select;
  396.         return $this;
  397.     }
  398.     /**
  399.      * Whereの設定
  400.      *
  401.      * @param $Where string WHERE文
  402.      * @param $Logical string 理論演算子
  403.      * @return $this
  404.      */
  405.     public function Where($Where$Logical 'AND')
  406.     {
  407.         $this->Where_[] = $Where;
  408.         $this->WhereLogical[] = $Logical;
  409.         return $this;
  410.     }
  411.     /**
  412.      * Paramsの設定
  413.      *
  414.      * @param string $Param
  415.      * @param string $Value
  416.      * @return $this
  417.      */
  418.     public function Param($Param$Value)
  419.     {
  420.         $this->Param_[$Param] = $Value;
  421.         return $this;
  422.     }
  423.     /**
  424.      * Paramsの一括設定
  425.      *
  426.      * @param array $params
  427.      * @return $this
  428.      */
  429.     public function Params(array $params)
  430.     {
  431.         foreach ($params as $Param => $Value) {
  432.             $this->Param($Param$Value);
  433.         }
  434.         return $this;
  435.     }
  436.     /**
  437.      * Sql文の設定
  438.      * @param string $Sql
  439.      * @return $this
  440.      */
  441.     public function Sql($Sql)
  442.     {
  443.         $this->Sql_ $Sql;
  444.         return $this;
  445.     }
  446.     /**
  447.      * Parameの設定
  448.      * @param array $Values
  449.      * @return $this
  450.      */
  451.     public function Values(array $Values)
  452.     {
  453.         $this->Values_ $Values;
  454.         return $this;
  455.     }
  456.     /**
  457.      * Setの定義 And でつなぐ
  458.      *
  459.      * @param string $Column
  460.      * @param string $Value 値
  461.      * @param string $Math 四則 =,!=,<,<=,>,>=,NULL等
  462.      * @param array $Param 未使用
  463.      * @return $this
  464.      */
  465.     public function Set($Column$Value$Math '=', array $Param = [])
  466.     {
  467.         $Math = isset($Math) ? $Math '=';
  468.         $this->Set_[] = array_merge(['Column' => $Column'Value' => $Value'Math' => $Math], $Param);
  469.         return $this;
  470.     }
  471.     /**
  472.      * Joinの定義
  473.      * @param string $Table
  474.      * @param string $On
  475.      * @param string $Join
  476.      * @return $this
  477.      */
  478.     public function Join($Table$On$Join 'LEFT')
  479.     {
  480.         $this->Join_[] = ['Table' => $Table'On' => $On'Join' => $Join];
  481.         return $this;
  482.     }
  483.     /**
  484.      * OrderBYの取得
  485.      * @param string $Column
  486.      * @param string $Sort 初期値 ASC DESC
  487.      * @return $this
  488.      */
  489.     public function Order($Column$Sort 'ASC')
  490.     {
  491.         $this->Order_[] = ['Column' => $Column'Sort' => $Sort];
  492.         return $this;
  493.     }
  494.     /**
  495.      * OrderBYの取得
  496.      * @param string $Column
  497.      * @return $this
  498.      */
  499.     public function OrderBy($OrderBy)
  500.     {
  501.         $this->OrderBy_ $OrderBy;
  502.         return $this;
  503.     }
  504.     /**
  505.      * GroupByの取得
  506.      * @param string $Group
  507.      * @return $this
  508.      */
  509.     public function GroupBy($Group)
  510.     {
  511.         $this->Group_ $Group;
  512.         return $this;
  513.     }
  514.     /**
  515.      * Selectsの取得
  516.      * @param string Selects
  517.      * @return $this
  518.      */
  519.     public function Selects($Column)
  520.     {
  521.         $this->Selects_[] = $Column;
  522.         return $this;
  523.     }
  524.     /**
  525.      * Columnの取得
  526.      * @param string $Column
  527.      * @return $this
  528.      */
  529.     public function Column($Column)
  530.     {
  531.         $this->Column_[] = $Column;
  532.         return $this;
  533.     }
  534.     /**
  535.      * Limitの設定
  536.      * @param $Limit int
  537.      * @param $Limit2 int
  538.      */
  539.     public function Limit($Limit$Limit2 '')
  540.     {
  541.         $this->Limit_ $Limit;
  542.         if ($Limit2){
  543.             $this->Limit_.= ','.$Limit2;
  544.         }
  545.         return $this;
  546.     }
  547.     /**
  548.      * Limitの設定
  549.      * @param int $OffSet
  550.      * @return $this
  551.      */
  552.     public function Offset($OffSet)
  553.     {
  554.         $this->OffSet_ $OffSet;
  555.         return $this;
  556.     }
  557.     /**
  558.      * SELECT SQL文の作成
  559.      *
  560.      * @return $this
  561.      */
  562.     protected function MakeSelect()
  563.     {
  564.         #SELRCT句の作成
  565.         $this->Sql_ 'SELECT ' $this->SetSelect() . ' ';
  566.         #FROM句の作成
  567.         $from 'FROM ' self::SetAsTable($this->Table_);
  568.         #Join句の作成
  569.         $join $this->SetJoin();
  570.         #Where句の作成
  571.         $where $this->SetWhere();
  572.         #GroupBy句の作成
  573.         $groupby self::SetGroupBy($this->Group_);
  574.         $this->Sql_ .= $from $join $where $groupby;
  575.         #OrderBY句の作製
  576.         $this->Sql_ .= $this->SetOrder();
  577.         #Limit句の作成
  578.         $this->Sql_ .= self::SetLimit($this->Limit_);
  579.         #OffSet句の作成
  580.         $this->Sql_ .= self::SetOffSet($this->OffSet_);
  581.         return $this;
  582.     }
  583.     /**
  584.      * UpDate の  SQL文の作成
  585.      *
  586.      * @return $this
  587.      */
  588.     protected function MakeUpdate()
  589.     {
  590.         $this->Sql_ 'UPDATE ' self::SetAsTable($this->Table_);
  591.         $this->Sql_ .= ' SET ';
  592.         $this->Sql_ .= $this->SetValues();
  593.         $this->Sql_ .= $this->SetWhere();
  594.         return $this;
  595.     }
  596.     /**
  597.      * Insert の  SQL文の作成
  598.      *
  599.      * @return string
  600.      */
  601.     protected function MakeInsert()
  602.     {
  603.         $this->Sql_ 'INSERT INTO ' $this->Table_;
  604.         $this->Sql_ .= ' SET ';
  605.         $this->Sql_ .= $this->SetValues(false);
  606.     }
  607.     /**
  608.      * Inserts の  SQL文の作成
  609.      *
  610.      * @return string
  611.      */
  612.     protected function MakeInserts()
  613.     {
  614.         $this->Sql_ "INSERT INTO {$this->Table_} ";
  615.         $this->Sql_ .= '(' implode(','array_keys(current($this->Values_))) . ')';
  616.         $this->Sql_ .= ' VALUES ';
  617.         $i 0;
  618.         foreach ($this->Values_ as $Values) {
  619.             $Re = [];
  620.             foreach ($Values as $Column => $Value) {
  621.                 $Param ':' $Column '_' $i;
  622.                 $Param $this->SetValue($Value$Param);
  623.                 $Re[] = $Param;
  624.             }
  625.             $i++;
  626.             $this->Sql_ .= '(' implode(','$Re) . '),';
  627.         }
  628.         $this->Sql_ trim($this->Sql_',');
  629.         # ON DUPLICATE KEY UPDATE の設定
  630.         if (count($this->Column_) > 0) {
  631.             $Keys = [];
  632.             foreach ($this->Column_ as $Column) {
  633.                 $Columns[] = preg_match('/\=/'$Column) ? $Column "{$Column} = VALUES({$Column})";
  634.             }
  635.             $this->Sql_ .= " ON DUPLICATE KEY UPDATE " implode(','$Columns);
  636.         }
  637.     }
  638.     protected function MakeDelete()
  639.     {
  640.         $this->Sql_ 'DELETE FROM ' $this->Table_;
  641.         $this->Sql_ .= $this->SetWhere(false);
  642.     }
  643.     /**
  644.      * SELECT 文に AS句を付ける
  645.      * @return string
  646.      */
  647.     protected function SetSelect()
  648.     {
  649.         $Re = [];
  650.         if (Count($this->Column_) > 0) {
  651.             $this->Select_ .= ($this->Select_ ',' '') . implode(','$this->Column_);
  652.         }
  653.         $Selects $this->Select_ explode(','$this->Select_) : [];
  654.         $Selects array_merge($Selects$this->Selects_);
  655.         if (count($Selects) < 1) {
  656.             return self::SELECT;
  657.         }
  658.         foreach ($Selects as $Select) {
  659.             $Re[] = self::SetAs($Select);
  660.         }
  661.         return implode(','$Re);
  662.     }
  663.     /**
  664.      * 外部連結を作成する
  665.      *
  666.      * @return string $Join
  667.      */
  668.     protected function SetJoin()
  669.     {
  670.         $Joins '';
  671.         foreach ($this->Join_ as $i => $Join) {
  672.             $As $i 1;
  673.             // TODO: BETWEEN ANDの対応
  674.             $Ons2 preg_split('/\s+(AND|OR)\s+/i'$Join['On'], -1PREG_SPLIT_DELIM_CAPTURE);
  675.             $Ons3 = [];
  676.             foreach ($Ons2 as $On2) {
  677.                 // TODO: 括弧付きの複雑な式の対応
  678.                 if (in_array(strtoupper($On2), [
  679.                     'AND',
  680.                     'OR',
  681.                 ])) {
  682.                     $Ons $On2;
  683.                 } else {
  684.                     // TODO: INの対応
  685.                     // TODO: ISの対応
  686.                     // $Ons = explode('=', $On2);
  687.                     // for ($i = 0; $i <= 1; $i++) {
  688.                     //     $Ons[$i] = trim((isset($Ons[$i]) ? $Ons[$i] : ''), ' ');
  689.                     //     $Ons[$i] = self::SetAs($Ons[$i], ($i ? $As : ''));
  690.                     // }
  691.                     // $Ons = $Ons[0] . ' = ' . $Ons[1];
  692.                     $Ons preg_split('/(!=|=|<>|<|>)/'$On2, -1PREG_SPLIT_NO_EMPTY PREG_SPLIT_DELIM_CAPTURE);
  693.                     foreach (array_chunk($Ons3) as $OnChunk) {
  694.                         foreach ($OnChunk as $i => $On) {
  695.                             if (($i 1) % === 0) {
  696.                                 $delim $On;
  697.                             } else {
  698.                                 $Ons[$i] = trim((isset($Ons[$i]) ? $Ons[$i] : ''), ' ');
  699.                                 $Ons[$i] = self::SetAs($Ons[$i], ($i $As ''));
  700.                             }
  701.                         }
  702.                         $Ons "{$Ons[0]} {$delim} {$Ons[2]}";
  703.                     }
  704.                 }
  705.                 $Ons3 array_merge($Ons3, (array)$Ons);
  706.             }
  707.             $Table self::SetAsTable($Join['Table'], $As);
  708.             $Joins .= ' ' strtoupper($Join['Join']) . ' JOIN ' $Table ' ON ' implode(' '$Ons3);
  709.         }
  710.         return $Joins;
  711.     }
  712.     /**
  713.      * 配列の値をセットする
  714.      * @param int|bool $Flg
  715.      * @return string
  716.      */
  717.     protected function SetValues($Flg true)
  718.     {
  719.         $Sql '';
  720.         $Values = [];
  721.         foreach ($this->Values_ as $Column => $Value) {
  722.             $Param ":{$Column}";
  723.             #値を パラメーターに設定する
  724.             $Param $this->SetValue($Value$Param);
  725.             $Values[] = ($Flg self::SetAs($Column) : $Column) . ' = ' $Param;
  726.         }
  727.         return implode(','$Values);
  728.     }
  729.     /**
  730.      * 値のセットをする
  731.      *
  732.      * @param string $Value
  733.      * @param string $Param
  734.      * @return mixed|string
  735.      */
  736.     protected function SetValue($Value$Param)
  737.     {
  738.         switch (true) {
  739.             case preg_match('/^(NOW\(\)|NOW)$/i'trim($Value)):
  740.                 $Param 'NOW()';
  741.                 break;
  742.             default:
  743.                 $this->Param_[$Param] = $Value;
  744.                 break;
  745.         }
  746.         return $Param;
  747.     }
  748.     /**
  749.      * WHERE句を作成する
  750.      *
  751.      * @Param int|bool $Flg
  752.      * @return string $Where
  753.      */
  754.     protected function SetWhere($Flg true)
  755.     {
  756.         $Where '';
  757.         foreach ($this->Set_ as $i => $Set) {
  758.             #論理記号を入れる ここで変更することは可能
  759.             $Logical 'AND';
  760.             $Where .= $Where {$Logical} " ' WHERE (';
  761.             #演算子のセット
  762.             $Where .= $this->MakeWhere($Set$Flg);
  763.         }
  764.         #$this->Set_を閉じる
  765.         $Where .= $Where ')' self::DEF;
  766.         foreach ($this->Where_ as $i => $Wheres) {
  767.             //* 要確認:下記の判定があると、WhereLogical に設定した値が入らずSQL構文エラーとなるため削除
  768.             //******** if ($Wheres === reset($this->Where_)) {
  769.             $Where .= $Where ' ' $this->WhereLogical[$i] : ' WHERE ';
  770.             //******** }
  771.             $Where .= ' ( ' $Wheres ' ) ';
  772.         }
  773.         return $Where;
  774.     }
  775.     protected function MakeWhere($Set$Flg true)
  776.     {
  777.         #カラムの設定
  778.         $Column $Flg self::SetAs($Set['Column']) : $Set['Column'];
  779.         $Param self::ParamKIgo preg_replace(self::AS_PATAN''$Column) . '_' $this->Num++;
  780.         $Math $Set['Math'];
  781.         $Value $Set['Value'];
  782.         switch (true) {
  783.             case 'IN' == $Math:
  784.                 $Math "IN ( " self::SetIn($Value,$Param) . " ) ";
  785.                 $Param '';
  786.                 break;
  787.             case 'NOT IN' == $Math:
  788.                 $Math "NOT IN ( " .self::SetIn($Value,$Param) . " ) ";
  789.                 $Param '';
  790.                 break;
  791.             case preg_match('/NOT NULL|NOTNULL|IS NOT NULL/i'$Value):
  792.             case preg_match('/NOT NULL|NOTNULL|IS NOT NULL/i'$Math):
  793.                 $Math 'IS NOT NULL';
  794.                 $Param '';
  795.                 break;
  796.             case is_null($Value);
  797.             case preg_match('/NULL|IS NULL/i'$Value):
  798.             case preg_match('/NULL|IS NULL/i'$Math):
  799.                 $Math 'IS NULL';
  800.                 $Param '';
  801.                 break;
  802.             case preg_match('/NOT LIKE/i'$Math):
  803.             case preg_match('/\%NOT LIKE\%/i'$Math):
  804.                 $Math 'NOT LIKE';
  805.                 $this->Param_[$Param] = '%' $Value '%';
  806.                 break;
  807.             case preg_match('/\%NOT LIKE/i'$Math):
  808.                 $Math 'NOT LIKE';
  809.                 $this->Param_[$Param] = '%' $Value;
  810.                 break;
  811.             case preg_match('/NOT LIKE\%/i'$Math):
  812.                 $Math 'NOT LIKE';
  813.                 $this->Param_[$Param] = $Value '%';
  814.                 break;
  815.             case preg_match('/LIKE/i'$Math):
  816.             case preg_match('/\%LIKE\%/i'$Math):
  817.                 $Math 'LIKE';
  818.                 $this->Param_[$Param] = '%' $Value '%';
  819.                 break;
  820.             case preg_match('/\%LIKE/i'$Math):
  821.                 $Math 'LIKE';
  822.                 $this->Param_[$Param] = '%' $Value;
  823.                 break;
  824.             case preg_match('/LIKE\%/i'$Math):
  825.                 $Math 'LIKE';
  826.                 $this->Param_[$Param] = $Value '%';
  827.                 break;
  828.             case preg_match('/BETWEEN/i'$Math):
  829.                 $separator preg_match('/\-/'$Value) ? '-' ',';
  830.                 $Betweens explode($separator$Value);
  831.                 $this->Param_[$Param '_f'] = isset($Betweens[0]) ? $Betweens[0] : 0;
  832.                 $this->Param_[$Param '_e'] = isset($Betweens[1]) ? $Betweens[1] : 0;
  833.                 $Param $Param '_f AND ' $Param '_f';
  834.                 break;
  835.             case 'EXISTS' == $Math:
  836.                 $As '';
  837.                 $Param '';
  838.                 $Column $Math ' ' $Column;
  839.                 break;
  840.             default:
  841.                 $this->Param_[$Param] = $Value;
  842.                 break;
  843.         }
  844.         return $Column ' ' $Math ' ' $Param ' ';
  845.     }
  846.     /**
  847.      * WHERE句 INの設定
  848.      * @param $Value string | array()
  849.      * @param $Param srting
  850.      * @return string
  851.      */
  852.     protected function SetIn($Value,$Param)
  853.     {
  854.         if (!is_array($Value)) {
  855.                 $Value explode(','$Value);
  856.             }
  857.         $Re=[];
  858.         foreach($Value as $i=>$Val){
  859.             $Params $Param '_' .$i;
  860.             $this->Param_[$Params] = $Val ;
  861.             $Re[] = $Params;
  862.         }
  863.         return implode(',',$Re);
  864.     }
  865.     /**
  866.      * Order()の設定
  867.      * OrderBy()の設定
  868.      *
  869.      * @return string $ReOrder
  870.      */
  871.     protected function SetOrder()
  872.     {
  873.         $ReOrder '';
  874.         if ($this->OrderBy_) {
  875.             $ReOrder ' ORDER BY ';
  876.             foreach (explode(','$this->OrderBy_) as $OrderBy) {
  877.                 $Orders[] = self::SetAs($OrderBy);
  878.             }
  879.             $ReOrder .= implode(','$Orders);
  880.         }
  881.         if (count($this->Order_) < 1) {
  882.             return $ReOrder;
  883.         }
  884.         if (!$ReOrder) {
  885.             $ReOrder ' ORDER BY ';
  886.         }
  887.         $Orders = [];
  888.         foreach ($this->Order_ as $Order) {
  889.             $Orders[] = self::SetAs($Order['Column']) . ' ' $Order['Sort'];
  890.         }
  891.         $ReOrder .= implode(','$Orders);
  892.         return $ReOrder;
  893.     }
  894.     /**
  895.      * GroupByの設定
  896.      *
  897.      * @param string $Group
  898.      * @return string GroupBy句
  899.      */
  900.     protected static function SetGroupBy($Group)
  901.     {
  902.         if (!$Group) {
  903.             return self::DEF;
  904.         }
  905.         $Re = [];
  906.         foreach (explode(','$Group) as $Column) {
  907.             $Re[] = self::SetAs($Column);
  908.         }
  909.         return ' GROUP BY ' implode(','$Re);
  910.     }
  911.     /**
  912.      * Limitの設定
  913.      *
  914.      * @param int $Limit
  915.      * @return string Limit句
  916.      */
  917.     protected static function SetLimit($Limit)
  918.     {
  919.         if (!$Limit) {
  920.             return self::DEF;
  921.         }
  922.         return ' Limit ' $Limit;
  923.     }
  924.     /**
  925.      * OffSetの設定
  926.      *
  927.      * @param int $OffSet
  928.      * @return string OffSet句
  929.      */
  930.     protected static function SetOffSet($OffSet)
  931.     {
  932.         if (!$OffSet) {
  933.             return self::DEF;
  934.         }
  935.         return ' OFFSET ' $OffSet;
  936.     }
  937.     /**
  938.      * カラムのアズ句を管理する
  939.      * Table,SELECT,
  940.      *
  941.      * @param string $Column
  942.      * @param string $As
  943.      * @return string $Column
  944.      */
  945.     protected static function SetAs($Column$As '')
  946.     {
  947.         #既にAS句がある
  948.         $Column trim($Column);
  949.         if (preg_match(self::AS_PATAN$Column)) {
  950.             return $Column;
  951.         }
  952.         #括弧等の記号が有る
  953.         if (preg_match('/\(|\)|\.|:/'$Column)) {
  954.             return $Column;
  955.         }
  956.         #カラム名でない(文字列リテラル)
  957.         if (preg_match('/^[\'"].*[\'"]$/'$Column)) {
  958.             return $Column;
  959.         }
  960.         #カラム名でない(数値)
  961.         if (preg_match('/^[0-9]/'$Column)) {
  962.             return $Column;
  963.         }
  964.         return self::AS_SYMBOL $As '.' $Column;
  965.     }
  966.     /**
  967.      * TABLのアズ句を管理する
  968.      * Table,SELECT,
  969.      *
  970.      * @param string $Table
  971.      * @param string $As
  972.      * @return string $Table
  973.      */
  974.     protected static function SetAsTable($Table$As '')
  975.     {
  976.         #既にAS句がある
  977.         if (preg_match('/ AS /'$Table)) {
  978.             return $Table;
  979.         }
  980.         return $Table ' AS ' self::AS_SYMBOL $As;
  981.     }
  982.     /**
  983.      * 1以上Sql分を表示する パラメーターは配列で表示
  984.      * =2 exit付き
  985.      */
  986.     protected function ViewSql()
  987.     {
  988.         if (!$this->ViewFlg) {
  989.             return;
  990.         }
  991.         echo $this->Sql_;
  992.         print_r($this->Param_);
  993.         if (== $this->ViewFlg) {
  994.             exit;
  995.         }
  996.     }
  997.     /*
  998.     http://dozo.matrix.jp/pear/index.php/PECL/pdo/fetch.html
  999.     execute()  準備したprepareに入っているSQL文を実行
  1000.     prepare()  値部分にパラメータを付けて実行待ち
  1001.     query()    prepareを使わずにSQL文を実行
  1002.     PDOException  エラーを投げる
  1003.     bindParam  与えられた変数を文字列としてパラメータに入れる
  1004.     bindValue  与えられた変数や数値を型を指定してパラメータに入れる※1
  1005.     PDO::PARAM_STR 変数の値を文字列として扱う
  1006.     PDO::PARAM_INT 変数の値を数値として扱う
  1007.     PDO::PARAM_BOOL
  1008.     PDO::PARAM_NULL (integer)
  1009.     :nameなど    パラメータ(:の後に任意の文字)
  1010.     PDO::FETCH_ASSOC   連想配列として取得します。※2
  1011.     PDO::ATTR_ORACLE_NULLS
  1012.     $stmt->bindParam(':name', $name, PDO::PARAM_STR);
  1013.     $stmt->bindValue(':value', 1, PDO::PARAM_INT);
  1014.     $stmt->bindValue(":value", null, PDO::PARAM_NULL); NULL を入れる
  1015.     */
  1016.     /**
  1017.      * クエリを実行し、結果をすべて取得
  1018.      *
  1019.      * @param  int|bool $Flg $ViewFlg 1 #SQl分をエコーで表示する パラメーターは配列 2 exit 付き
  1020.      * @return array
  1021.      * 空の戻り値がbArrayを返す を DEF 初期値 に統一
  1022.      */
  1023.     public function FetchAll($Flg false)
  1024.     {
  1025.         if ($Flg) {
  1026.             $this->ViewFlg $Flg;
  1027.         }
  1028.         if (!$this->Sql_) {
  1029.             return self::RE;
  1030.         }
  1031.         $this->ViewSql();
  1032.         $label = [
  1033.             'Sql_' => $this->Sql_,
  1034.             'Param_' => $this->Param_,
  1035.         ];
  1036.         try {
  1037.             return $this->getCached(function () {
  1038.                 $Re = [];
  1039.                 if (count($this->Param_) > 0) {
  1040.                     #PDOStatementの取得
  1041.                     $this->Stmt $this->Connect[self::READ]->prepare($this->Sql_, [\PDO::ATTR_CURSOR => \PDO::CURSOR_FWDONLY]);
  1042.                     #パラメーターのセット
  1043.                     $this->SetParameter();
  1044.                     $this->Stmt->execute();
  1045.                 } else {
  1046.                     $this->Stmt $this->Connect[self::READ]->query($this->Sql_);
  1047.                 }
  1048.                 $Re $this->Stmt->fetchAll(\PDO::FETCH_ASSOC);
  1049.                 return Count($Re) > $Re self::RE;
  1050.             }, $label);
  1051.         } finally {
  1052.             $this->Initialize();
  1053.         }
  1054.     }
  1055.     /**
  1056.      * クエリを実行し、結果を1行取得
  1057.      *
  1058.      * @param int|bool $Flg
  1059.      * @return array
  1060.      *
  1061.      * 空の戻り値がboolean =falseを返す FetchAllと統一
  1062.      */
  1063.     public function Fetch($Flg false)
  1064.     {
  1065.         if ($Flg) {
  1066.             $this->ViewFlg $Flg;
  1067.         }
  1068.         if (!$this->Sql_) {
  1069.             return self::RE;
  1070.         }
  1071.         $this->ViewSql();
  1072.         if (count($this->Param_) > 0) {
  1073.             $stmt $this->Connect[self::READ]->prepare($this->Sql_, [\PDO::ATTR_CURSOR => \PDO::CURSOR_FWDONLY]);
  1074.             foreach ($this->Param_ as $Param => $Value) {
  1075.                 $stmt->bindValue($Param$Value\PDO::PARAM_STR);
  1076.             }
  1077.             $stmt->execute();
  1078.         } else {
  1079.             $stmt $this->Connect[self::READ]->query($this->Sql_);
  1080.         }
  1081.         $this->Initialize();
  1082.         $Value $stmt->fetch(\PDO::FETCH_ASSOC);
  1083.         return $Value;
  1084.     }
  1085.     protected function FOREIGN_KEY($Flg 0)
  1086.     {
  1087.         $this->Stmt $this->Connect[self::WRITE]->prepare("SET FOREIGN_KEY_CHECKS={$Flg};");
  1088.         $this->Stmt->execute();
  1089.     }
  1090.     public function Exec($Flg false)
  1091.     {
  1092.         if ($Flg) {
  1093.             $this->ViewFlg $Flg;
  1094.         }
  1095.         if (!$this->Sql_) {
  1096.             return self::RE;
  1097.         }
  1098.         #外部キーリレーションシップの解除
  1099.         if (!is_null($this->ForeignKey_)) {
  1100.             $this->FOREIGN_KEY($this->ForeignKey_);
  1101.         }
  1102.         $this->ViewSql();
  1103.         $this->Stmt $this->Connect[self::WRITE]->prepare($this->Sql_, [\PDO::ATTR_CURSOR => \PDO::CURSOR_FWDONLY]);
  1104.         #パラメーターのセット
  1105.         $this->SetParameter();
  1106.         #実行
  1107.         $Num $this->Stmt->execute();
  1108.         #初期化
  1109.         $this->Initialize();
  1110.         return $Num;
  1111.     }
  1112.     /**
  1113.      * パラメーターをセットする
  1114.      * @param $this->Param_
  1115.      * @param $this->Stmt
  1116.      */
  1117.     protected function SetParameter()
  1118.     {
  1119.         foreach ($this->Param_ as $Param => $Value) {
  1120.             //echo gettype($Value);
  1121.             switch (gettype($Value)) {
  1122.                 case 'NULL':
  1123.                     $this->Stmt->bindValue($Paramnull\PDO::PARAM_NULL);
  1124.                     break;
  1125.                 case 'boolean':
  1126.                       $Value =  $Value ;
  1127.                 case 'integer':
  1128.                     if (preg_match('/^0+[0-9]+$/'$Value)){ #頭が0の数字は 文字として判断
  1129.                     $this->Stmt->bindValue($Param$Value\PDO::PARAM_STR);
  1130.                     break;
  1131.                     }
  1132.                     $this->Stmt->bindValue($Param$Value\PDO::PARAM_INT);
  1133.                     break;
  1134.                 case 'double':
  1135.                 case 'string':
  1136.                 default:
  1137.                     $this->Stmt->bindValue($Param$Value\PDO::PARAM_STR);
  1138.                     break;
  1139.             }
  1140.         }
  1141.     }
  1142.     /**
  1143.      * トランザクション: 開始
  1144.      *
  1145.      * @return bool
  1146.      */
  1147.     public function beginTransaction()
  1148.     {
  1149.         return $this->Connect[self::WRITE]->beginTransaction();
  1150.     }
  1151.     /**
  1152.      * トランザクション: コミット
  1153.      *
  1154.      * @return bool
  1155.      */
  1156.     public function commit()
  1157.     {
  1158.         return $this->Connect[self::WRITE]->commit();
  1159.     }
  1160.     /**
  1161.      * トランザクション: ロールバック
  1162.      *
  1163.      * @return bool
  1164.      */
  1165.     public function rollBack()
  1166.     {
  1167.         return $this->Connect[self::WRITE]->rollBack();
  1168.     }
  1169. }