<?php
/*
* Copyright (c) 2018, 北京博习园教育科技有限公司
* All rights reserved.
*
* 文件名称: xmodel.php
* 摘 要: 模型公共类
* 作 者: 刘泉皓
* $Id$
*/ /**
* 数据库连接类,依赖 PDO_MYSQL 扩展
* walkor:在 https://github.com/auraphp/Aura.SqlQuery 的基础上修改而成
* liuquanhao:在 https://github.com/walkor/mysql 的基础上修改而成
*/ require_once __DIR__ . '/' . '../../../config/config.php';
require_once __DIR__ . '/' . '../function/cache.php';
require_once __DIR__ . '/' . '../function/comm_func.php'; class XModel
{
/**
* SELECT
*
* @var array
*/
protected $union = array(); /**
* 是否是更新
*
* @var bool
*/
protected $for_update = false; /**
* 选择的列
*
* @var array
*/
protected $cols = array(); /**
* 从哪些表里面 SELECT
*
* @var array
*/
protected $from = array(); /**
* $from 当前的 key
*
* @var int
*/
protected $from_key = -1; /**
* GROUP BY 的列
*
* @var array
*/
protected $group_by = array(); /**
* HAVING 条件数组.
*
* @var array
*/
protected $having = array(); /**
* HAVING 语句中绑定的值.
*
* @var array
*/
protected $bind_having = array(); /**
* 每页多少条记录
*
* @var int
*/
protected $paging = 10; /**
* sql 中绑定的值
*
* @var array
*/
protected $bind_values = array(); /**
* WHERE 条件.
*
* @var array
*/
protected $where = array(); /**
* WHERE 语句绑定的值
*
* @var array
*/
protected $bind_where = array(); /**
* ORDER BY 的列
*
* @var array
*/
protected $order_by = array(); /**
* ORDER BY 的排序方式,默认为升序
*
* @var bool
*/
protected $order_asc = true;
/**
* SELECT 多少记录
*
* @var int
*/
protected $limit = 0; /**
* 返回记录的游标
*
* @var int
*/
protected $offset = 0; /**
* flags 列表
*
* @var array
*/
protected $flags = array(); /**
* 操作哪个表
*
* @var string
*/
protected $table; /**
* 表.列 和 last-insert-id 映射
*
* @var array
*/
protected $last_insert_id_names = array(); /**
* INSERT 或者 UPDATE 的列
*
* @param array
*/
protected $col_values; /**
* 返回的列
*
* @var array
*/
protected $returning = array(); /**
* sql 的类型 SELECT INSERT DELETE UPDATE
*
* @var string
*/
protected $type = ''; /**
* pdo 实例
*
* @var PDO
*/
protected $pdo; /**
* PDOStatement 实例
*
* @var PDOStatement
*/
protected $sQuery; /**
* 数据库用户名密码等配置
*
* @var array
*/
protected $readSettings = array();
protected $writeSettings = array(); /**
* sql 的参数
*
* @var array
*/
protected $parameters = array(); /**
* 最后一条直行的 sql
*
* @var string
*/
protected $lastSql = ''; /**
* 使用memcache
*
* @var object
*/
protected $mem = null;
/**
* memcache key
*
* @var string
*/
protected $memKey = '';
/**
* memcache active time
*
* @var int
*/
protected $memTime = 0;
/**
* log
*
* @var boolean
*/
protected $log = false;
protected $logName = __CLASS__; /**
* 是否执行成功
*
* @var bool
*/
protected $success = false; /**
* 构造函数
*/
public function __construct($dbname = '')
{
if (!empty($dbname)) {
$this->database($dbname);
} // 使用惰性连接
//$this->connect();
} /*
* 选择数据库
*/
public function database($dbname)
{
switch ($dbname) {
case 'tongzhuo_ask_db':
$this->selectAskHost();
break;
case 'tongzhuonet_db':
$this->selectTznetHost();
break;
case 'tongzhuo_weixin_db':
$this->selectWeixinHost();
break;
case 'tongzhuo_user_db':
$this->selectUserHost();
break;
case 'tongzhuo_examination_db':
$this->selectExaminationHost();
break;
case 'tongzhuo_tv_db':
$this->selectTvHost();
break;
case 'tongzhuo_db':
$this->selectTzHost();
break;
default:
throw new Exception('Not found database!');
}
return $this;
} /*
* 使用memcache
*/
public function mem($key = '', $activeTime = 0)
{
global $mem;
$this->mem = $mem;
$this->memKey = $key;
$this->memTime = $activeTime;
return $this;
} /**
* 选择哪些列
*
* @param string|array $cols
* @return self
*/
public function select($cols = '*')
{
$this->type = 'SELECT';
if (!is_array($cols)) {
$cols = explode(',', $cols);
}
$this->cols($cols);
return $this;
} /**
* 从哪个表删除
*
* @param string $table
* @return self
*/
public function delete($table)
{
$this->type = 'DELETE';
$this->table = $this->quoteName($table);
$this->fromRaw($this->quoteName($table));
return $this;
} /**
* 从哪个表hash删除
*
* @param string $pre
* @param string $salt
* @return self
*/
public function deleteHash($pre, $salt)
{
$table = $this->hashTable($pre, $salt);
return $this->delete($table);
} /**
* 更新哪个表
*
* @param string $table
* @return self
*/
public function update($table)
{
$this->type = 'UPDATE';
$this->table = $this->quoteName($table);
return $this;
} /**
* 更新哪个hash表
*
* @param string $pre
* @param string $salt
* @return self
*/
public function updateHash($pre, $salt)
{
$table = $this->hashTable($pre, $salt);
return $this->update($table);
} /**
* 向哪个表插入
*
* @param string $table
* @return self
*/
public function insert($table)
{
$this->type = 'INSERT';
$this->table = $this->quoteName($table);
return $this;
} /**
* 向哪个hash表插入
*
* @param string $pre
* @param string $hash
* @return self
*/
public function insertHash($pre, $salt)
{
$table = $this->hashTable($pre, $salt);
return $this->insert($table);
} /**
* from 哪个表
*
* @param string $table
* @return self
*/
public function from($table)
{
return $this->fromRaw($this->quoteName($table));
} /**
* from 哪个hash表
*
* @param string $pre
* @param string $salt
* @return self
*/
public function fromHash($pre, $salt)
{
$table = $this->hashTable($pre, $salt);
return $this->from($table);
} /**
* from的表
*
* @param string $table
* @return self
*/
public function fromRaw($table)
{
$this->from[] = array($table);
$this->from_key++;
return $this;
} /**
*
* 子查询
*
* @param string $table
* @param string $name The alias name for the sub-select.
* @return self
*/
public function fromSubSelect($table, $name)
{
$this->from[] = array("($table) AS " . $this->quoteName($name));
$this->from_key++;
return $this;
} /**
* 增加 join 语句
*
* @param string $table
* @param string $cond
* @param string $type
* @return self
* @throws Exception
*/
public function join($table, $cond = null, $type = '')
{
return $this->joinInternal($type, $table, $cond);
} /**
* 增加 join 语句
*
* @param string $join inner, left, natural
* @param string $table
* @param string $cond
* @return self
* @throws Exception
*/
protected function joinInternal($join, $table, $cond = null)
{
if (!$this->from) {
throw new Exception('Cannot join() without from()');
} $join = strtoupper(ltrim("$join JOIN"));
$table = $this->quoteName($table);
$cond = $this->fixJoinCondition($cond);
$this->from[$this->from_key][] = rtrim("$join $table $cond");
return $this;
} /**
* left join
*
* @param string $table
* @param string $cond
* @return self
* @throws Exception
*/
public function leftJoin($table, $cond = null)
{
return $this->joinInternal('LEFT', $table, $cond);
} /**
* right join
*
* @param string $table
* @param string $cond
* @return self
* @throws Exception
*/
public function rightJoin($table, $cond = null)
{
return $this->joinInternal('RIGHT', $table, $cond);
} /**
* joinSubSelect
*
* @param string $join inner, left, natural
* @param string $spec
* @param string $name sub-select 的别名
* @param string $cond
* @return self
* @throws Exception
*/
public function joinSubSelect($join, $spec, $name, $cond = null)
{
if (!$this->from) {
throw new Exception('Cannot join() without from() first.');
} $join = strtoupper(ltrim("$join JOIN"));
$name = $this->quoteName($name);
$cond = $this->fixJoinCondition($cond);
$this->from[$this->from_key][] = rtrim("$join ($spec) AS $name $cond");
return $this;
} /**
* group by 语句
*
* @param array $cols
* @return self
*/
public function groupBy(array $cols)
{
foreach ($cols as $col) {
$this->group_by[] = $this->quoteNamesIn($col);
}
return $this;
} /**
* having 语句
*
* @param string $cond
* @return self
*/
public function having($cond)
{
$this->addClauseCondWithBind('having', 'AND', func_get_args());
return $this;
} /**
* or having 语句
*
* @param string $cond The HAVING condition.
* @return self
*/
public function orHaving($cond)
{
$this->addClauseCondWithBind('having', 'OR', func_get_args());
return $this;
} /*
* 重连tv读写数据库
*/
protected function selectTvHost()
{
$this->readSettings['user'] = $GLOBALS['user_tv_read'];
$this->readSettings['password'] = $GLOBALS['pw_tv_read'];
$this->readSettings['host'] = $GLOBALS['host_tv_read'];
$this->readSettings['port'] = $GLOBALS['port_tv_read'];
$this->readSettings['dbname'] = $GLOBALS['database_tv_read'];
$this->writeSettings['user'] = $GLOBALS['user_tv_write'];
$this->writeSettings['password'] = $GLOBALS['pw_tv_write'];
$this->writeSettings['host'] = $GLOBALS['host_tv_write'];
$this->writeSettings['port'] = $GLOBALS['port_tv_write'];
$this->writeSettings['dbname'] = $GLOBALS['database_tv_write'];
} /*
* 重连ask读写数据库
*/
protected function selectAskHost()
{
$this->readSettings['user'] = $GLOBALS['user_ask_read'];
$this->readSettings['password'] = $GLOBALS['pw_ask_read'];
$this->readSettings['host'] = $GLOBALS['host_ask_read'];
$this->readSettings['port'] = $GLOBALS['port_ask_read'];
$this->readSettings['dbname'] = $GLOBALS['database_ask_read'];
$this->writeSettings['user'] = $GLOBALS['user_ask_write'];
$this->writeSettings['password'] = $GLOBALS['pw_ask_write'];
$this->writeSettings['host'] = $GLOBALS['host_ask_write'];
$this->writeSettings['port'] = $GLOBALS['port_ask_write'];
$this->writeSettings['dbname'] = $GLOBALS['database_ask_write'];
}
/*
* 重连net读写数据库
*/
protected function selectTznetHost()
{
$this->readSettings['user'] = $GLOBALS['user_tz_read'];
$this->readSettings['password'] = $GLOBALS['pw_tz_read'];
$this->readSettings['host'] = $GLOBALS['host_tz_read'];
$this->readSettings['port'] = $GLOBALS['port_tz_read'];
$this->readSettings['dbname'] = $GLOBALS['database_tz_read'];
$this->writeSettings['user'] = $GLOBALS['user_tz_write'];
$this->writeSettings['password'] = $GLOBALS['pw_tz_write'];
$this->writeSettings['host'] = $GLOBALS['host_tz_write'];
$this->writeSettings['port'] = $GLOBALS['port_tz_write'];
$this->writeSettings['dbname'] = $GLOBALS['database_tz_write'];
}
/*
* 重连weixin读写数据库
*/
protected function selectWeixinHost()
{
$this->readSettings['user'] = $GLOBALS['user_wx_read'];
$this->readSettings['password'] = $GLOBALS['pw_wx_read'];
$this->readSettings['host'] = $GLOBALS['host_wx_read'];
$this->readSettings['port'] = $GLOBALS['port_wx_read'];
$this->readSettings['dbname'] = $GLOBALS['database_wx_read'];
$this->writeSettings['user'] = $GLOBALS['user_wx_write'];
$this->writeSettings['password'] = $GLOBALS['pw_wx_write'];
$this->writeSettings['host'] = $GLOBALS['host_wx_write'];
$this->writeSettings['port'] = $GLOBALS['port_wx_write'];
$this->writeSettings['dbname'] = $GLOBALS['database_wx_write'];
}
/*
* 重连用户日志读写数据库
*/
protected function selectUserHost()
{
$this->readSettings['user'] = $GLOBALS['user_user_read'];
$this->readSettings['password'] = $GLOBALS['pw_user_read'];
$this->readSettings['host'] = $GLOBALS['host_user_read'];
$this->readSettings['port'] = $GLOBALS['port_user_read'];
$this->readSettings['dbname'] = $GLOBALS['database_user_read'];
$this->writeSettings['user'] = $GLOBALS['user_user_write'];
$this->writeSettings['password'] = $GLOBALS['pw_user_write'];
$this->writeSettings['host'] = $GLOBALS['host_user_write'];
$this->writeSettings['port'] = $GLOBALS['port_user_write'];
$this->writeSettings['dbname'] = $GLOBALS['database_user_write'];
}
/*
* 模拟考试读写数据库
*/
protected function selectExaminationHost()
{
$this->readSettings['user'] = $GLOBALS['user_ex_read'];
$this->readSettings['password'] = $GLOBALS['pw_ex_read'];
$this->readSettings['host'] = $GLOBALS['host_ex_read'];
$this->readSettings['port'] = $GLOBALS['port_ex_read'];
$this->readSettings['dbname'] = $GLOBALS['database_ex_read'];
$this->writeSettings['user'] = $GLOBALS['user_user_write'];
$this->writeSettings['password'] = $GLOBALS['pw_ex_write'];
$this->writeSettings['host'] = $GLOBALS['host_ex_write'];
$this->writeSettings['port'] = $GLOBALS['port_ex_write'];
$this->writeSettings['dbname'] = $GLOBALS['database_ex_write'];
}
/*
* 重连tongzhuo读写数据库
*/
protected function selectTzHost()
{
$this->readSettings['user'] = $GLOBALS['user_one_read'];
$this->readSettings['password'] = $GLOBALS['pw_one_read'];
$this->readSettings['host'] = $GLOBALS['host_one_read'];
$this->readSettings['port'] = $GLOBALS['port_one_read'];
$this->readSettings['dbname'] = $GLOBALS['database_one_read'];
$this->writeSettings['user'] = $GLOBALS['user_one_write'];
$this->writeSettings['password'] = $GLOBALS['pw_one_write'];
$this->writeSettings['host'] = $GLOBALS['host_one_write'];
$this->writeSettings['port'] = $GLOBALS['port_one_write'];
$this->writeSettings['dbname'] = $GLOBALS['database_one_write'];
} /**
* 创建 PDO 实例
*/
protected function connect()
{
if ($this->type == 'SELECT') {
if (
empty($this->readSettings['dbname']) &&
empty($this->readSettings['host']) &&
empty($this->readSettings['port']) &&
empty($this->readSettings['user']) &&
empty($this->readSettings['password'])) {
throw new Exception('Database configuration fail!');
}
$dsn = 'mysql:dbname=' . $this->readSettings['dbname'] .
';host=' . $this->readSettings['host'] . ';port=' . $this->readSettings['port'] .
';charset=utf8';
$this->pdo = new PDO(
$dsn,
$this->readSettings['user'],
$this->readSettings['password']
);
} else {
if (
empty($this->writeSettings['dbname']) &&
empty($this->writeSettings['host']) &&
empty($this->writeSettings['port']) &&
empty($this->writeSettings['user']) &&
empty($this->writeSettings['password'])) {
throw new Exception('Database configuration fail!');
}
$dsn = 'mysql:dbname=' . $this->writeSettings['dbname'] .
';host=' . $this->writeSettings['host'] . ';port=' . $this->writeSettings['port'] .
';charset=utf8';
$this->pdo = new PDO(
$dsn,
$this->writeSettings['user'],
$this->writeSettings['password']
);
}
$this->pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
$this->pdo->setAttribute(PDO::ATTR_STRINGIFY_FETCHES, false);
$this->pdo->setAttribute(PDO::ATTR_EMULATE_PREPARES, false);
} /*
* 清空本次mem设置信息
*/
protected function resetMem()
{
$this->mem = null;
$this->memKey = '';
$this->memTime = 0;
} /**
* 关闭连接
*/
public function closeConnection()
{
$this->pdo = null;
}
/**
*
* 设置 SQL_CALC_FOUND_ROWS 标记.
*
* @param bool $enable
* @return self
*/
public function calcFoundRows($enable = true)
{
$this->setFlag('SQL_CALC_FOUND_ROWS', $enable);
return $this;
} /**
* 设置 SQL_CACHE 标记
*
* @param bool $enable
* @return self
*/
public function cache($enable = true)
{
$this->setFlag('SQL_CACHE', $enable);
return $this;
} /**
* 设置 SQL_NO_CACHE 标记
*
* @param bool $enable
* @return self
*/
public function noCache($enable = true)
{
$this->setFlag('SQL_NO_CACHE', $enable);
return $this;
} /**
* 设置 STRAIGHT_JOIN 标记.
*
* @param bool $enable
* @return self
*/
public function straightJoin($enable = true)
{
$this->setFlag('STRAIGHT_JOIN', $enable);
return $this;
} /**
* 设置 HIGH_PRIORITY 标记
*
* @param bool $enable
* @return self
*/
public function highPriority($enable = true)
{
$this->setFlag('HIGH_PRIORITY', $enable);
return $this;
} /**
* 设置 SQL_SMALL_RESULT 标记
*
* @param bool $enable
* @return self
*/
public function smallResult($enable = true)
{
$this->setFlag('SQL_SMALL_RESULT', $enable);
return $this;
} /**
* 设置 SQL_BIG_RESULT 标记
*
* @param bool $enable
* @return self
*/
public function bigResult($enable = true)
{
$this->setFlag('SQL_BIG_RESULT', $enable);
return $this;
} /**
* 设置 SQL_BUFFER_RESULT 标记
*
* @param bool $enable
* @return self
*/
public function bufferResult($enable = true)
{
$this->setFlag('SQL_BUFFER_RESULT', $enable);
return $this;
} /**
* 设置 DISTINCT 标记
*
* @param bool $enable
* @return self
*/
public function distinct($enable = true)
{
$this->setFlag('DISTINCT', $enable);
return $this;
} /**
* 设置 LOW_PRIORITY 标记
*
* @param bool $enable
* @return self
*/
public function lowPriority($enable = true)
{
$this->setFlag('LOW_PRIORITY', $enable);
return $this;
} /**
* 设置 IGNORE 标记
*
* @param bool $enable
* @return self
*/
public function ignore($enable = true)
{
$this->setFlag('IGNORE', $enable);
return $this;
} /**
* 设置 QUICK 标记
*
* @param bool $enable
* @return self
*/
public function quick($enable = true)
{
$this->setFlag('QUICK', $enable);
return $this;
} /**
* 设置 DELAYED 标记
*
* @param bool $enable
* @return self
*/
public function delayed($enable = true)
{
$this->setFlag('DELAYED', $enable);
return $this;
} /**
* 设置 FOR UPDATE 标记
*
* @param bool $enable
* @return self
*/
public function forUpdate($enable = true)
{
$this->for_update = (bool) $enable;
return $this;
} /**
* 设置每页多少条记录
*
* @param int $paging
* @return self
*/
public function setPaging($paging)
{
$this->paging = (int) $paging;
return $this;
} /**
* 获取每页多少条记录
*
* @return int
*/
public function getPaging()
{
return $this->paging;
} /**
* 序列化
*
* @return string
*/
public function __toString()
{
$union = '';
if ($this->union) {
$union = implode(' ', $this->union) . ' ';
}
return $union . $this->build();
} /**
* 获取绑定在占位符上的值
*/
public function getBindValues()
{
switch ($this->type) {
case 'SELECT':
return $this->getBindValuesSELECT();
case 'DELETE':
case 'UPDATE':
case 'INSERT':
return $this->getBindValuesCOMMON();
default:
throw new Exception("type err");
}
} /**
* 获取绑定在占位符上的值
*
* @return array
*/
public function getBindValuesSELECT()
{
$bind_values = $this->bind_values;
$i = 1;
foreach ($this->bind_where as $val) {
$bind_values[$i] = $val;
$i++;
}
foreach ($this->bind_having as $val) {
$bind_values[$i] = $val;
$i++;
}
return $bind_values;
} /**
*
* SELECT选择哪些列
*
* @param mixed $key
* @param string $val
* @return void
*/
protected function addColSELECT($col, $alias)
{
if (is_string($col)) {
$this->cols[$alias] = $col;
} else {
$this->addColWithAlias($alias);
}
} /**
* SELECT 增加选择的列
*
* @param string $spec
*/
protected function addColWithAlias($spec)
{
$parts = explode(' ', trim($spec));
$count = count($parts);
if ($count == 2) {
$this->cols[$parts[1]] = $parts[0];
} elseif ($count == 3 && strtoupper($parts[1]) == 'AS') {
$this->cols[$parts[2]] = $parts[0];
} else {
$this->cols[] = $spec;
}
} /**
* quote
*
* @param string $cond
* @return string
*
*/
protected function fixJoinCondition($cond)
{
if (!$cond) {
return '';
} $cond = $this->quoteNamesIn($cond); if (strtoupper(substr(ltrim($cond), 0, 3)) == 'ON ') {
return $cond;
} if (strtoupper(substr(ltrim($cond), 0, 6)) == 'USING ') {
return $cond;
} return 'ON ' . $cond;
} /**
* inner join
*
* @param string $table
* @param string $cond
* @return self
* @throws Exception
*/
public function innerJoin($table, $cond = null)
{
return $this->joinInternal('INNER', $table, $cond);
}
/**
* 设置每页的记录数量
*
* @param int $page
* @return self
*/
public function page($page)
{
$this->limit = 0;
$this->offset = 0; $page = (int) $page;
if ($page > 0) {
$this->limit = $this->paging;
$this->offset = $this->paging * ($page - 1);
}
return $this;
} /**
* union
*
* @return self
*/
public function union()
{
$this->union[] = $this->build() . ' UNION';
$this->reset();
return $this;
} /**
* unionAll
*
* @return self
*/
public function unionAll()
{
$this->union[] = $this->build() . ' UNION ALL';
$this->reset();
return $this;
} /**
* 重置
*/
protected function reset()
{
$this->resetFlags();
$this->cols = array();
$this->from = array();
$this->from_key = -1;
$this->where = array();
$this->group_by = array();
$this->having = array();
$this->order_by = array();
$this->limit = 0;
$this->offset = 0;
$this->for_update = false;
} /**
* 清除所有数据
*/
protected function resetAll()
{
$this->union = array();
$this->for_update = false;
$this->cols = array();
$this->from = array();
$this->from_key = -1;
$this->group_by = array();
$this->having = array();
$this->bind_having = array();
$this->paging = 10;
$this->bind_values = array();
$this->where = array();
$this->bind_where = array();
$this->order_by = array();
$this->limit = 0;
$this->offset = 0;
$this->flags = array();
$this->table = '';
$this->last_insert_id_names = array();
$this->col_values = array();
$this->returning = array();
$this->parameters = array();
} /**
* 创建 SELECT SQL
*
* @return string
*/
protected function buildSELECT()
{
return 'SELECT'
. $this->buildFlags()
. $this->buildCols()
. $this->buildFrom()
. $this->buildWhere()
. $this->buildGroupBy()
. $this->buildHaving()
. $this->buildOrderBy()
. $this->buildLimit()
. $this->buildForUpdate();
} /**
* 创建 DELETE SQL
*/
protected function buildDELETE()
{
return 'DELETE'
. $this->buildFlags()
. $this->buildFrom()
. $this->buildWhere()
. $this->buildOrderBy()
. $this->buildLimit()
. $this->buildReturning();
} /**
* 生成 SELECT 列语句
*
* @return string
* @throws Exception
*/
protected function buildCols()
{
if (!$this->cols) {
throw new Exception('No columns in the SELECT.');
} $cols = array();
foreach ($this->cols as $key => $val) {
if (is_int($key)) {
$cols[] = $this->quoteNamesIn($val);
} else {
$cols[] = $this->quoteNamesIn("$val AS $key");
}
} return $this->indentCsv($cols);
} /**
* 生成 FROM 语句.
*
* @return string
*/
protected function buildFrom()
{
if (!$this->from) {
return '';
} $refs = array();
foreach ($this->from as $from) {
$refs[] = implode(' ', $from);
}
return ' FROM' . $this->indentCsv($refs);
} /**
* 生成 GROUP BY 语句.
*
* @return string
*/
protected function buildGroupBy()
{
if (!$this->group_by) {
return '';
}
return ' GROUP BY' . $this->indentCsv($this->group_by);
} /**
* 生成 HAVING 语句.
*
* @return string
*/
protected function buildHaving()
{
if (!$this->having) {
return '';
}
return ' HAVING' . $this->indent($this->having);
} /**
* 生成 FOR UPDATE 语句
*
* @return string
*/
protected function buildForUpdate()
{
if (!$this->for_update) {
return '';
}
return ' FOR UPDATE';
} /**
* where
*
* @param string|array $cond
* @return self
*/
public function where($cond)
{
if (is_array($cond)) {
foreach ($cond as $key => $val) {
if (is_string($key)) {
$this->addWhere('AND', array($key, $val));
} else {
$this->addWhere('AND', array($val));
}
}
} else {
$this->addWhere('AND', func_get_args());
}
return $this;
} /**
* or where
*
* @param string|array $cond
* @return self
*/
public function orWhere($cond)
{
if (is_array($cond)) {
foreach ($cond as $key => $val) {
if (is_string($key)) {
$this->addWhere('OR', array($key, $val));
} else {
$this->addWhere('OR', array($val));
}
}
} else {
$this->addWhere('OR', func_get_args());
}
return $this;
} /**
* limit
*
* @param int $limit
* @return self
*/
public function limit($limit)
{
$this->limit = (int) $limit;
return $this;
} /**
* limit offset
*
* @param int $offset
* @return self
*/
public function offset($offset)
{
$this->offset = (int) $offset;
return $this;
} /**
* orderby.
*
* @param array $cols
* @return self
*/
public function orderBy(array $cols)
{
return $this->addOrderBy($cols);
} /**
* order by ASC OR DESC
*
* @param array $cols
* @param bool $order_asc
* @return self
*/
public function orderByASC(array $cols, $order_asc = true)
{
$this->order_asc = $order_asc;
return $this->addOrderBy($cols);
} /**
* order by DESC
*
* @param array $cols
* @return self
*/
public function orderByDESC(array $cols)
{
$this->order_asc = false;
return $this->addOrderBy($cols);
} // -------------abstractquery----------
/**
* 返回逗号分隔的字符串
*
* @param array $list
* @return string
*/
protected function indentCsv(array $list)
{
return ' ' . implode(',', $list);
} /**
* 返回空格分隔的字符串
*
* @param array $list
* @return string
*/
protected function indent(array $list)
{
return ' ' . implode(' ', $list);
} /**
* 批量为占位符绑定值
*
* @param array $bind_values
* @return self
*
*/
public function bindValues(array $bind_values)
{
foreach ($bind_values as $key => $val) {
$this->bindValue($key, $val);
}
return $this;
} /**
* 单个为占位符绑定值
*
* @param string $name
* @param mixed $value
* @return self
*/
public function bindValue($name, $value)
{
$this->bind_values[$name] = $value;
return $this;
} /**
* 生成 flag
*
* @return string
*/
protected function buildFlags()
{
if (!$this->flags) {
return '';
}
return ' ' . implode(' ', array_keys($this->flags));
} /**
* 设置 flag.
*
* @param string $flag
* @param bool $enable
*/
protected function setFlag($flag, $enable = true)
{
if ($enable) {
$this->flags[$flag] = true;
} else {
unset($this->flags[$flag]);
}
} /**
* 重置 flag
*/
protected function resetFlags()
{
$this->flags = array();
} /**
*
* 添加 where 语句
*
* @param string $andor 'AND' or 'OR
* @param array $conditions
* @return self
*
*/
protected function addWhere($andor, $conditions)
{
$this->addClauseCondWithBind('where', $andor, $conditions);
return $this;
} /**
* 添加条件和绑定值
*
* @param string $clause where 、having等
* @param string $andor AND、OR等
* @param array $conditions
*/
protected function addClauseCondWithBind($clause, $andor, $conditions)
{
$cond = array_shift($conditions);
$cond = $this->quoteNamesIn($cond); $bind = &$this->{"bind_{$clause}"};
foreach ($conditions as $value) {
$bind[] = $value;
} $clause = &$this->$clause;
if ($clause) {
$clause[] = "$andor $cond";
} else {
$clause[] = $cond;
}
} /**
* 生成 where 语句
*
* @return string
*/
protected function buildWhere()
{
if (!$this->where) {
return '';
}
return ' WHERE' . $this->indent($this->where);
} /**
* 增加 order by
*
* @param array $spec The columns and direction to order by.
* @return self
*/
protected function addOrderBy(array $spec)
{
foreach ($spec as $col) {
$this->order_by[] = $this->quoteNamesIn($col);
}
return $this;
} /**
* 生成 order by 语句
*
* @return string
*/
protected function buildOrderBy()
{
if (!$this->order_by) {
return '';
} if ($this->order_asc) {
return ' ORDER BY' . $this->indentCsv($this->order_by) . ' ASC';
} else {
return ' ORDER BY' . $this->indentCsv($this->order_by) . ' DESC';
}
} /**
* 生成 limit 语句
*
* @return string
*/
protected function buildLimit()
{
$has_limit = $this->type == 'DELETE' || $this->type == 'UPDATE';
$has_offset = $this->type == 'SELECT'; if ($has_offset && $this->limit) {
$clause = " LIMIT {$this->limit}";
if ($this->offset) {
$clause .= " OFFSET {$this->offset}";
}
return $clause;
} elseif ($has_limit && $this->limit) {
return " LIMIT {$this->limit}";
}
return '';
} /**
* Quotes
*
* @param string $spec
* @return string|array
*/
public function quoteName($spec)
{
$spec = trim($spec);
$seps = array(' AS ', ' ', '.');
foreach ($seps as $sep) {
$pos = strripos($spec, $sep);
if (false !== $pos) {
return $this->quoteNameWithSeparator($spec, $sep, $pos);
}
}
return $this->replaceName($spec);
} /**
* 指定分隔符的 Quotes
*
* @param string $spec
* @param string $sep
* @param int $pos
* @return string
*/
protected function quoteNameWithSeparator($spec, $sep, $pos)
{
$len = strlen($sep);
$part1 = $this->quoteName(substr($spec, 0, $pos));
$part2 = $this->replaceName(substr($spec, $pos + $len));
return "{$part1}{$sep}{$part2}";
} /**
* Quotes "table.col" 格式的字符串
*
* @param string $text
* @return string|array
*/
public function quoteNamesIn($text)
{
$list = $this->getListForQuoteNamesIn($text);
$last = count($list) - 1;
$text = null;
foreach ($list as $key => $val) {
if (($key + 1) % 3) {
$text .= $this->quoteNamesInLoop($val, $key == $last);
}
}
return $text;
} /**
* 返回 quote 元素列表
*
* @param string $text
* @return array
*/
protected function getListForQuoteNamesIn($text)
{
$apos = "'";
$quot = '"';
return preg_split(
"/(($apos+|$quot+|\\$apos+|\\$quot+).*?\\2)/",
$text,
-1,
PREG_SPLIT_DELIM_CAPTURE
);
} /**
* 循环 quote
*
* @param string $val
* @param bool $is_last
* @return string
*/
protected function quoteNamesInLoop($val, $is_last)
{
if ($is_last) {
return $this->replaceNamesAndAliasIn($val);
}
return $this->replaceNamesIn($val);
} /**
* 替换成别名
*
* @param string $val
* @return string
*/
protected function replaceNamesAndAliasIn($val)
{
$quoted = $this->replaceNamesIn($val);
$pos = strripos($quoted, ' AS ');
if ($pos !== false) {
$alias = $this->replaceName(substr($quoted, $pos + 4));
$quoted = substr($quoted, 0, $pos) . " AS $alias";
}
return $quoted;
} /**
* Quotes name
*
* @param string $name
* @return string
*/
protected function replaceName($name)
{
$name = trim($name);
if ($name == '*') {
return $name;
}
return '`' . $name . '`';
} /**
* Quotes
*
* @param string $text
* @return string|array
*/
protected function replaceNamesIn($text)
{
$is_string_literal = strpos($text, "'") !== false
|| strpos($text, '"') !== false;
if ($is_string_literal) {
return $text;
} $word = '[a-z_][a-z0-9_]*'; $find = "/(\\b)($word)\\.($word)(\\b)/i"; $repl = '$1`$2`.`$3`$4'; $text = preg_replace($find, $repl, $text); return $text;
} // ---------- insert --------------
/**
* 设置 `table.column` 与 last-insert-id 的映射
*
* @param array $last_insert_id_names
*/
public function setLastInsertIdNames(array $last_insert_id_names)
{
$this->last_insert_id_names = $last_insert_id_names;
} /**
* insert into.
*
* @param string $table
* @return self
*/
public function into($table)
{
$this->table = $this->quoteName($table);
return $this;
} /**
* 生成 INSERT 语句
*
* @return string
*/
protected function buildINSERT()
{
return 'INSERT'
. $this->buildFlags()
. $this->buildInto()
. $this->buildValuesForInsert()
. $this->buildReturning();
} /**
* 生成 INTO 语句
*
* @return string
*/
protected function buildInto()
{
return " INTO " . $this->table;
} /**
* PDO::lastInsertId()
*
* @param string $col
* @return mixed
*/
public function getLastInsertIdName($col)
{
$key = str_replace('`', '', $this->table) . '.' . $col;
if (isset($this->last_insert_id_names[$key])) {
return $this->last_insert_id_names[$key];
} return null;
} /**
* 设置一列,如果有第二各参数,则把第二个参数绑定在占位符上
*
* @param string $col
* @return self
*/
public function col($col)
{
return call_user_func_array(array($this, 'addCol'), func_get_args());
} /**
* 设置多列
*
* @param array $cols
* @return self
*/
public function cols(array $cols)
{
if ($this->type == 'SELECT') {
foreach ($cols as $key => $val) {
$this->addColSELECT($key, $val);
}
return $this;
}
return $this->addCols($cols);
} /**
* 直接设置列的值
*
* @param string $col
* @param string $value
* @return self
*/
public function set($col, $value)
{
return $this->setCol($col, $value);
} /**
* 为 INSERT 语句绑定值
*
* @return string
*/
protected function buildValuesForInsert()
{
return ' (' . $this->indentCsv(array_keys($this->col_values)) . ') VALUES (' .
$this->indentCsv(array_values($this->col_values)) . ')';
} // ------update-------
/**
* 更新哪个表
*
* @param string $table
* @return self
*/
public function table($table)
{
$this->table = $this->quoteName($table);
return $this;
} /**
* 生成完整 SQL 语句
*
* @return string
* @throws Exception
*/
protected function build()
{
switch ($this->type) {
case 'DELETE':
return $this->buildDELETE();
case 'INSERT':
return $this->buildINSERT();
case 'UPDATE':
return $this->buildUPDATE();
case 'SELECT':
return $this->buildSELECT();
}
throw new Exception("type empty");
} /**
* 生成更新的 SQL 语句
*/
protected function buildUPDATE()
{
return 'UPDATE'
. $this->buildFlags()
. $this->buildTable()
. $this->buildValuesForUpdate()
. $this->buildWhere()
. $this->buildOrderBy()
. $this->buildLimit()
. $this->buildReturning();
} /**
* 哪个表
*
* @return string
*/
protected function buildTable()
{
return " {$this->table}";
} /**
* 为更新语句绑定值
*
* @return string
*/
protected function buildValuesForUpdate()
{
$values = array();
foreach ($this->col_values as $col => $value) {
$values[] = "{$col} = {$value}";
}
return ' SET' . $this->indentCsv($values);
} // ----------Dml---------------
/**
* 获取绑定的值
*
* @return array
*/
public function getBindValuesCOMMON()
{
$bind_values = $this->bind_values;
$i = 1;
foreach ($this->bind_where as $val) {
$bind_values[$i] = $val;
$i++;
}
return $bind_values;
} /**
* 设置列
*
* @param string $col
* @return self
*/
protected function addCol($col)
{
$key = $this->quoteName($col);
$this->col_values[$key] = ":$col";
$args = func_get_args();
if (count($args) > 1) {
$this->bindValue($col, $args[1]);
}
return $this;
} /**
* 设置多个列
*
* @param array $cols
* @return self
*/
protected function addCols(array $cols)
{
foreach ($cols as $key => $val) {
if (is_int($key)) {
$this->addCol($val);
} else {
$this->addCol($key, $val);
}
}
return $this;
} /**
* 设置单列的值
*
* @param string $col .
* @param string $value
* @return self
*/
protected function setCol($col, $value)
{
if ($value === null) {
$value = 'NULL';
} $key = $this->quoteName($col);
$value = $this->quoteNamesIn($value);
$this->col_values[$key] = $value;
return $this;
} /**
* 增加返回的列
*
* @param array $cols
* @return self
*
*/
protected function addReturning(array $cols)
{
foreach ($cols as $col) {
$this->returning[] = $this->quoteNamesIn($col);
}
return $this;
} /**
* 生成 RETURNING 语句
*
* @return string
*/
protected function buildReturning()
{
if (!$this->returning) {
return '';
}
return ' RETURNING' . $this->indentCsv($this->returning);
} /**
* 执行
*
* @param string $query
* @param string $parameters
* @throws PDOException
*/
protected function execute($query, $parameters = "")
{
try {
$this->connect();
$this->sQuery = @$this->pdo->prepare($query);
$this->bindMore($parameters);
if (!empty($this->parameters)) {
foreach ($this->parameters as $param) {
$parameters = explode("\x7F", $param);
$this->sQuery->bindParam($parameters[0], $parameters[1]);
}
}
$this->success = $this->sQuery->execute();
} catch (PDOException $e) {
// 服务端断开时重连一次
if ($e->errorInfo[1] == 2006 || $e->errorInfo[1] == 2013) {
$this->closeConnection();
try {
$this->connect();
$this->sQuery = $this->pdo->prepare($query);
$this->bindMore($parameters);
if (!empty($this->parameters)) {
foreach ($this->parameters as $param) {
$parameters = explode("\x7F", $param);
$this->sQuery->bindParam($parameters[0], $parameters[1]);
}
}
$this->success = $this->sQuery->execute();
} catch (PDOException $ex) {
$this->rollBackTrans();
throw $ex;
}
} else {
$this->rollBackTrans();
$msg = $e->getMessage();
$err_msg = "SQL:" . $this->lastSQL() . " " . $msg;
$exception = new PDOException($err_msg, (int) $e->getCode());
throw $exception;
}
}
if ($this->log) {
$message = sprintf("%s|%s", $query, implode(',', $this->parameters));
comm_log($this->logName, $message);
}
$this->parameters = array();
} /**
* 绑定
*
* @param string $para
* @param string $value
*/
public function bind($para, $value)
{
if (is_string($para)) {
$this->parameters[sizeof($this->parameters)] = ":" . $para . "\x7F" . $value;
} else {
$this->parameters[sizeof($this->parameters)] = $para . "\x7F" . $value;
}
} /**
* 绑定多个
*
* @param array $parray
*/
public function bindMore($parray)
{
if (empty($this->parameters) && is_array($parray)) {
$columns = array_keys($parray);
foreach ($columns as $i => &$column) {
$this->bind($column, $parray[$column]);
}
}
} /**
* 执行 SQL
*
* @param string $query
* @param array $params
* @param int $fetchmode
* @return mixed
*/
public function query($query = '', $params = null, $fetchmode = PDO::FETCH_ASSOC)
{
$query = trim($query);
if (empty($query)) {
$query = $this->build();
if (!$params) {
$params = $this->getBindValues();
}
} else {
$this->parseType($query);
}
$this->resetAll();
$this->lastSql = $query;
if ($this->type == 'SELECT' && $this->mem) {
if (empty($this->memKey)) {
$this->memKey = $query . ' [' . implode(',', $params) . ']';
} $buf = $this->mem->get($this->memKey);
if ($buf !== false) {
$this->resetMem();
return $buf;
}
}
$this->execute($query, $params);
$rawStatement = explode(" ", $query);
$statement = strtolower(trim($rawStatement[0]));
if ($statement === 'select' || $statement === 'show') {
$rs = $this->sQuery->fetchAll($fetchmode);
if ($statement === 'select' && $this->mem) {
$this->mem->set($this->memKey, $rs, 0, $this->memTime);
$this->resetMem();
}
return $rs;
} elseif ($statement === 'update' || $statement === 'delete') {
return $this->sQuery->rowCount();
} elseif ($statement === 'insert') {
if ($this->sQuery->rowCount() > 0) {
return $this->lastInsertId();
}
} else {
return null;
} return null;
} /**
* 返回一列
*
* @param string $query
* @param array $params
* @return array
*/
public function column($query = '', $params = null)
{
$query = trim($query);
if (empty($query)) {
$query = $this->build();
if (!$params) {
$params = $this->getBindValues();
}
}
$this->resetAll();
$this->lastSql = $query;
if ($this->mem) {
if (empty($this->memKey)) {
$this->memKey = $query . ' [' . implode(',', $params) . ']';
} $buf = $this->mem->get($this->memKey);
if ($buf !== false) {
$this->resetMem();
return $buf;
}
}
if (empty($this->type)) {
$this->parseType($query);
}
$this->execute($query, $params);
$columns = $this->sQuery->fetchAll(PDO::FETCH_NUM);
$column = null;
foreach ($columns as $cells) {
$column[] = $cells[0];
}
if ($this->mem) {
$this->mem->set($this->memKey, $column, 0, $this->memTime);
$this->resetMem();
}
return $column;
} /**
* 返回一行
*
* @param string $query
* @param array $params
* @param int $fetchmode
* @return array
*/
public function row($query = '', $params = null, $fetchmode = PDO::FETCH_ASSOC)
{
$query = trim($query);
if (empty($query)) {
$query = $this->build();
if (!$params) {
$params = $this->getBindValues();
}
} $this->resetAll();
$this->lastSql = $query;
if ($this->mem) {
if (empty($this->memKey)) {
$this->memKey = $query . ' [' . implode(',', $params) . ']';
}
$buf = $this->mem->get($this->memKey);
if ($buf !== false) {
$this->resetMem();
return $buf;
}
}
if (empty($this->type)) {
$this->parseType($query);
}
$this->execute($query, $params);
$rs = $this->sQuery->fetch($fetchmode);
if ($this->mem) {
$this->mem->set($this->memKey, $rs, 0, $this->memTime);
$this->resetMem();
}
return $rs;
} /**
* 返回单个值
*
* @param string $query
* @param array $params
* @return string
*/
public function single($query = '', $params = null)
{
$query = trim($query);
if (empty($query)) {
$query = $this->build();
if (!$params) {
$params = $this->getBindValues();
}
}
$this->resetAll();
if ($this->mem) {
if (empty($this->memKey)) {
$this->memKey = $query . ' [' . implode(',', $params) . ']';
}
$buf = $this->mem->get($this->memKey);
if ($buf !== false) {
$this->resetMem();
return $buf;
}
}
if (empty($this->type)) {
$this->parseType($query);
}
$this->execute($query, $params);
$rs = $this->sQuery->fetchColumn();
if ($this->mem) {
$this->mem->set($this->memKey, $rs, 0, $this->memTime);
$this->resetMem();
}
return $rs;
} /**
* 返回 lastInsertId
*
* @return string
*/
public function lastInsertId()
{
return $this->pdo->lastInsertId();
} /**
* 返回最后一条执行的 sql
*
* @return string
*/
public function lastSQL()
{
return $this->lastSql;
} /**
* 开始事务
*/
public function beginTrans()
{
try {
return $this->pdo->beginTransaction();
} catch (PDOException $e) {
// 服务端断开时重连一次
if ($e->errorInfo[1] == 2006 || $e->errorInfo[1] == 2013) {
$this->closeConnection();
$this->connect();
return $this->pdo->beginTransaction();
} else {
throw $e;
}
}
} /**
* 提交事务
*/
public function commitTrans()
{
return $this->pdo->commit();
} /**
* 事务回滚
*/
public function rollBackTrans()
{
if ($this->pdo) {
if ($this->pdo->inTransaction()) {
return $this->pdo->rollBack();
}
}
return true;
} /**
* hash分表
*/
protected function hashTable($pre, $salt)
{
if (empty($salt)) {
return $pre . '0';
} $salt = strtolower($salt);
if (is_numeric($salt) && strlen($salt) > 1) {
$hash = substr($salt, -2, 2);
} else if (preg_match("/^[0-9a-z]{1}$/", substr($salt, -1, 1))) {
$hash = substr($salt, -1, 1);
} else {
return $pre . '0';
}
return $pre . $hash;
} public function log($logName = '')
{
$this->log = true;
if (!empty($logName)) {
$this->logName = $logName;
}
return $this;
} /**
* 没有设置type,也不是select(),update(),insert(),delete()方法,则分析sql语句,设置type
*/
public function parseType($query)
{
$query = trim($query);
if (empty($query)) {
$this->type = 'SELECT';
}
$this->type = strtoupper(explode(' ', $query)[0]);
}
/**
* (废弃,已自动判断)
* SELECT:读库
* 其他:写库
*/
public function setType($type) {
$this->type = strtoupper($type);
}
}

PDO连接数据库-Xmodel的更多相关文章

  1. 【转】php pdo连接数据库 解决中文乱码问题(wordpress mysql 问号?? ??)

    原文链接:http://blog.csdn.net/ysydao/article/details/11002295 PHP 用pdo连接数据库时出现中文乱码问题解决办法 1.array(PDO::MY ...

  2. PDO连接数据库

    PDO连接数据库 PDO简介和配置 php.ini extension=php_pdo.dll extension=php_pdo_myysql.dll PDO连接MYSQL new PDO(&quo ...

  3. 使用PDO连接数据库 查询和插入乱码的解决方法

    问题:PDO连接数据库后,查询和插入中文到数据库,出现乱码,如图: 解决方法: 法1: try{ $opts_values = array(PDO::MYSQL_ATTR_INIT_COMMAND=& ...

  4. PHP5中使用PDO连接数据库的方法

    PDO(PHP Data Object) 是PHP 中加入的东西,是PHP 5新加入的一个重大功能,因为在PHP 5以前的php4/php3都是一堆的数据库扩展来跟各个数据库的连接和处理,php_my ...

  5. php PDO连接数据库

    [PDO是啥] PDO是PHP 5新加入的一个重大功能,因为在PHP 5以前的php4/php3都是一堆的数据库扩展来跟各个数据库的连接和处理,什么 php_mysql.dll.php_pgsql.d ...

  6. php+mysql+pdo连接数据库

    1.$pdo = new PDO("mysql:host=localhost;dbname=test","root","123456");/ ...

  7. 封装PDO连接数据库代码

    废话不说直接上代码: <?php class DB { protected static $_connect; protected $dsn, $pdo; protected $_data, $ ...

  8. 使用PDO连接数据库

    PDO(PHP数据对象) 是一个轻量级的.具有兼容接口的PHP数据连接拓展,是一个PHP官方的PECL库,随PHP 5.1发布,需要PHP 5的面向对象支持,因而在更早的版本上无法使用.它所提供的数据 ...

  9. pdo 连接数据库 报错 could not find driver 解决方法

    在windows 下,调试一个PHP程序时,报了这个错误, could not find driver 原来我的这个程序中用到了PDO对象, 连接mysql 5.  在PHP的默认设置中,只打开了ph ...

随机推荐

  1. 浏览器模式&用户代理字符串(IE)

    问题问题描述今天在做项目的时候,QA部门提了一个Bug,在一个搜索列表中,搜索栏为空时刷新页面,却触发了搜索功能,并且列表显示出<未搜索到结果> 环境IE11 问题原因 QA的IE11用户 ...

  2. C#实现无物理边距 可打印区域的绘图\打印 z

    经常在开发实际的应用程序中,需要用到图形绘制和打印程序.如何实现完整的精确打印和绘图是需要注意许多细节地方的.最近在遇到打印问题的时候,仔细研究一阵,总结这篇博文,写得有点杂乱,看文要还请费点神. 基 ...

  3. 【ASP.NET 问题】ASP.NET 网站404页面返回200,或者302的解决办法

    做网站在优化网站时遇到了跳转404页面却返回 200.302状态的问题,这样的话搜索引擎会认为这个页面是一个正常的页面,但是这个页面实际是个错误页面,虽然对访问的用户而言,HTTP状态码是“404”还 ...

  4. CentOS 7 安装 Oracle 11.2.0.4

    一.安装环境 CentOS Linux release 7.2.1511 (Core) Oracle Database 11g Release 2 (11.2.0.4) 二.安装前准备 2.1 修改主 ...

  5. JAVA与C#的区别

    Java和C#都是编程的语言,它们是两个不同方向的两种语言 相同点: 他们都是面向对象的语言,也就是说,它们都能实现面向对象的思想(封装,继承,多态) 区别: 1.c#中的命名空间是namespace ...

  6. Hadoop小文件存储方案

    原文地址:https://www.cnblogs.com/ballwql/p/8944025.html HDFS总体架构 在介绍文件存储方案之前,我觉得有必要先介绍下关于HDFS存储架构方面的一些知识 ...

  7. BizTalk RosettaNet解决方案之Loopback

    本教程使用 BizTalk Accelerator for RosettaNet (BTARN) 在一台计算机上模拟本组织与合作伙伴组织之间的流程实施情况. 创建本组织 “BizTalk <版本 ...

  8. Atitit s2018.5 s5 doc list on com pc.docx  Acc 112237553.docx Acc baidu netdisk.docx Acc csdn 18821766710 attilax main num.docx Atiitt put post 工具 开发工具dev tool test.docx Atiitt 腾讯图像分类相册管家.docx

    Atitit s2018.5 s5  doc list on com pc.docx  Acc  112237553.docx Acc baidu netdisk.docx Acc csdn 1882 ...

  9. PhpStorm连接Docker容器配置xdebug断点调试

    本教程主要演示xdebug在PhpStorm中配置方法. 一.环境说明 1.Mac笔记本(本教程演示过程使用的是Mac OS操作系统,和windows环境是有区别的,这一点需要特别注意): 2.在Ma ...

  10. Java编程的逻辑 (92) - 函数式数据处理 (上)

    本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http:/ ...