core.php 148 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667266826692670267126722673267426752676267726782679268026812682268326842685268626872688268926902691269226932694269526962697269826992700270127022703270427052706270727082709271027112712271327142715271627172718271927202721272227232724272527262727272827292730273127322733273427352736273727382739274027412742274327442745274627472748274927502751275227532754275527562757275827592760276127622763276427652766276727682769277027712772277327742775277627772778277927802781278227832784278527862787278827892790279127922793279427952796279727982799280028012802280328042805280628072808280928102811281228132814281528162817281828192820282128222823282428252826282728282829283028312832283328342835283628372838283928402841284228432844284528462847284828492850285128522853285428552856285728582859286028612862286328642865286628672868286928702871287228732874287528762877287828792880288128822883288428852886288728882889289028912892289328942895289628972898289929002901290229032904290529062907290829092910291129122913291429152916291729182919292029212922292329242925292629272928292929302931293229332934293529362937293829392940294129422943294429452946294729482949295029512952295329542955295629572958295929602961296229632964296529662967296829692970297129722973297429752976297729782979298029812982298329842985298629872988298929902991299229932994299529962997299829993000300130023003300430053006300730083009301030113012301330143015301630173018301930203021302230233024302530263027302830293030303130323033303430353036303730383039304030413042304330443045304630473048304930503051305230533054305530563057305830593060306130623063306430653066306730683069307030713072307330743075307630773078307930803081308230833084308530863087308830893090309130923093309430953096309730983099310031013102310331043105310631073108310931103111311231133114311531163117311831193120312131223123312431253126312731283129313031313132313331343135313631373138313931403141314231433144314531463147314831493150315131523153315431553156315731583159316031613162316331643165316631673168316931703171317231733174317531763177317831793180318131823183318431853186318731883189319031913192319331943195319631973198319932003201320232033204320532063207320832093210321132123213321432153216321732183219322032213222322332243225322632273228322932303231323232333234323532363237323832393240324132423243324432453246324732483249325032513252325332543255325632573258325932603261326232633264326532663267326832693270327132723273327432753276327732783279328032813282328332843285328632873288328932903291329232933294329532963297329832993300330133023303330433053306330733083309331033113312331333143315331633173318331933203321332233233324332533263327332833293330333133323333333433353336333733383339334033413342334333443345334633473348334933503351335233533354335533563357335833593360336133623363336433653366336733683369337033713372337333743375337633773378337933803381338233833384338533863387338833893390339133923393339433953396339733983399340034013402340334043405340634073408340934103411341234133414341534163417341834193420342134223423342434253426342734283429343034313432343334343435343634373438343934403441344234433444344534463447344834493450345134523453345434553456345734583459346034613462346334643465346634673468346934703471347234733474347534763477347834793480348134823483348434853486348734883489349034913492349334943495349634973498349935003501350235033504350535063507350835093510351135123513351435153516351735183519352035213522352335243525352635273528352935303531353235333534353535363537353835393540354135423543354435453546354735483549355035513552355335543555355635573558355935603561356235633564356535663567356835693570357135723573357435753576357735783579358035813582358335843585358635873588358935903591359235933594359535963597359835993600360136023603360436053606360736083609361036113612361336143615361636173618361936203621362236233624362536263627
  1. <?php
  2. /**
  3. * CoreMVC核心模块
  4. *
  5. * @version 1.3.2
  6. * @author Z <602000@gmail.com>
  7. * @link http://www.coremvc.cn/
  8. */
  9. /**
  10. * 定义(define)
  11. */
  12. class core {
  13. /**
  14. * 配置文件或配置数组
  15. *
  16. * @link http://www.coremvc.cn/api/core/config.php
  17. */
  18. private static $config = '';
  19. private static $connect = '';
  20. private static $view = '';
  21. /**
  22. * 初始化函数(可继承)
  23. *
  24. * @link http://www.coremvc.cn/api/core/init.php
  25. * @param mixed $config
  26. * @param mixed &$variable
  27. * @return mixed
  28. */
  29. public static function init($config = null, &$variable = null) {
  30. // 引用参数处理
  31. $self_flag = $variable === null;
  32. if ($self_flag) {
  33. $current_config = &self::$config;
  34. } else {
  35. $current_config = &$variable;
  36. }
  37. // 导入配置文件
  38. if (is_string($current_config) && $current_config !== '') {
  39. $current_config = self::_init_file($current_config);
  40. } elseif ($self_flag && $current_config === '') {
  41. $current_config = self::_init_file('@' . __CLASS__ . '/config.php');
  42. }
  43. if (!is_array($current_config)) {
  44. $current_config = array();
  45. }
  46. // 导入环境变量
  47. $import_config = self::_init_env('config');
  48. if ($import_config !== array()) {
  49. $current_config = array_merge($current_config, $import_config);
  50. }
  51. // 配置参数处理
  52. if (is_bool($config)) {
  53. if ($config) {
  54. // 完全清空配置
  55. $current_config = array();
  56. } else {
  57. // 直接返回配置
  58. return $current_config;
  59. }
  60. } elseif (is_array($config)) {
  61. $count = count($config);
  62. if ($count > 0 && isset($config [$count - 1])) {
  63. // 返回多个属性
  64. $return_config = array();
  65. for ($i = 0; $i < $count; $i++) {
  66. $value = $config [$i];
  67. $return_config [$i] = isset($current_config [$value]) ? $current_config [$value] : '';
  68. }
  69. return $return_config;
  70. } elseif ($count > 0) {
  71. // 导入参数数组
  72. $current_config = array_merge($current_config, $config);
  73. }
  74. } elseif (is_string($config)) {
  75. if (strtolower(strrchr($config, '.')) === '.php') {
  76. // 导入配置文件
  77. $import_config = self::_init_file($config);
  78. if ($import_config !== array()) {
  79. $current_config = array_merge($current_config, $import_config);
  80. }
  81. } else {
  82. // 直接返回属性
  83. return isset($current_config [$config]) ? $current_config [$config] : '';
  84. }
  85. }
  86. // 需要初始化的函数
  87. if ($self_flag) {
  88. self::_init_extension($current_config);
  89. self::_init_autoload($current_config);
  90. }
  91. return $current_config;
  92. }
  93. /**
  94. * 存根函数(可继承)
  95. *
  96. * @link http://www.coremvc.cn/api/core/stub.php
  97. * @param bool $autoload_enable
  98. * @param string $autoload_path
  99. * @param string $autoload_extensions
  100. * @param bool $autoload_prepend
  101. * @return bool
  102. */
  103. public static function stub($autoload_enable = null, $autoload_path = null, $autoload_extensions = null, $autoload_prepend = null) {
  104. // 初始化自动载入功能
  105. $array = array();
  106. isset($autoload_enable) and $array ['autoload_enable'] = $autoload_enable;
  107. isset($autoload_path) and $array ['autoload_path'] = $autoload_path;
  108. isset($autoload_extensions) and $array ['autoload_extensions'] = $autoload_extensions;
  109. isset($autoload_prepend) and $array ['autoload_prepend'] = $autoload_prepend;
  110. self::_stub_autoload($array);
  111. // 判断访问或者引用
  112. foreach (debug_backtrace() as $row) {
  113. switch ($row ['function']) {
  114. case 'include' :
  115. case 'require' :
  116. case 'include_once' :
  117. case 'require_once' :
  118. case 'spl_autoload_call' :
  119. return false;
  120. }
  121. }
  122. return true;
  123. }
  124. /**
  125. * 入口函数(可继承)
  126. *
  127. * @link http://www.coremvc.cn/api/core/main.php
  128. * @param bool $framework_enable
  129. * @param string $framework_require
  130. * @param string $framework_mdoule
  131. * @param string $framework_action
  132. * @param string $framework_parameter
  133. * @return bool
  134. */
  135. public static function main($framework_enable = null, $framework_require = null, $framework_module = null, $framework_action = null, $framework_parameter = null) {
  136. // 一次跳转功能
  137. $config = self::init(false);
  138. if (!empty($config ['framework_function'])) {
  139. $function = $config ['framework_function'];
  140. if (!is_array($function)) {
  141. $function = (array) $function;
  142. }
  143. foreach ($function as $function_key => $function_value) {
  144. unset($function[$function_key]);
  145. break;
  146. }
  147. if ($function === array()) {
  148. $function = '';
  149. }
  150. self::init(array('framework_function' => $function));
  151. if (is_callable($function_value)) {
  152. self::_main_framework_first(true);
  153. return call_user_func($function_value, $framework_enable, $framework_require, $framework_module, $framework_action, $framework_parameter);
  154. }
  155. }
  156. // 入口参数处理
  157. isset($framework_enable) and $config ['framework_enable'] = $framework_enable;
  158. if (empty($config ['framework_enable']) || !is_string($config ['framework_enable'])) {
  159. $return_array = array();
  160. } else {
  161. $return_array = explode(',', $config ['framework_enable']);
  162. }
  163. // 框架控制功能
  164. if (!empty($config ['framework_enable'])) {
  165. isset($framework_require) and $config ['framework_require'] = $framework_require;
  166. isset($framework_module) and $config ['framework_module'] = $framework_module;
  167. isset($framework_action) and $config ['framework_action'] = $framework_action;
  168. isset($framework_parameter) and $config ['framework_parameter'] = $framework_parameter;
  169. return self::_main_framework($config, $return_array);
  170. }
  171. // 模拟文件隐藏效果
  172. if (!in_array('manual', $return_array)) {
  173. self::_main_hide($config);
  174. }
  175. return false;
  176. }
  177. /**
  178. * 路径函数
  179. *
  180. * @link http://www.coremvc.cn/api/core/path.php
  181. * @param string $filename
  182. * @param string $filetype
  183. * @return string
  184. */
  185. public static function path($filename, $filetype = null) {
  186. switch ($filetype) {
  187. case 'extension' :
  188. $filepath = self::_path_extension($filename);
  189. break;
  190. case 'config' :
  191. $filepath = self::_path_config($filename);
  192. break;
  193. case 'template' :
  194. $filepath = self::_path_template($filename);
  195. break;
  196. default :
  197. $filepath = self::_path_file($filename);
  198. if ($filepath === null) {
  199. $filepath = $filename;
  200. }
  201. break;
  202. }
  203. return $filepath;
  204. }
  205. /**
  206. * 视图函数(可继承)
  207. *
  208. * @link http://www.coremvc.cn/api/core/view.php
  209. * @param mixed $_view_file_global
  210. * @param array $_view_vars
  211. * @param string $_view_type
  212. * @param bool $_view_show
  213. * @return string
  214. */
  215. public static function view($_view_file_global = null, $_view_vars = null, $_view_type = null, $_view_show = null) {
  216. // 视图全局参数
  217. self::_view_variable($_view_file_global);
  218. if (is_string($_view_file_global)) {
  219. $_view_file = $_view_file_global;
  220. } else {
  221. return self::$view;
  222. }
  223. // 视图参数处理
  224. $_view_init = self::init(false);
  225. $_view_config = array(
  226. 'template_search' => isset($_view_init ['template_search']) ? $_view_init ['template_search'] : '',
  227. 'template_replace' => isset($_view_init ['template_replace']) ? $_view_init ['template_replace'] : '',
  228. 'template_type' => isset($_view_init ['template_type']) ? $_view_init ['template_type'] : '',
  229. );
  230. isset($_view_type) and $_view_config ['template_type'] = $_view_type;
  231. // 视图数据处理
  232. if ($_view_config ['template_search'] !== '' && $_view_config ['template_search'] !== $_view_config ['template_replace']) {
  233. $_view_file2 = self::_path_template(str_replace($_view_config ['template_search'], $_view_config ['template_replace'], $_view_file));
  234. } else {
  235. $_view_file2 = self::_path_template($_view_file);
  236. }
  237. $_view_vars2 = is_array($_view_vars) ? array_merge(self::$view, $_view_vars) : self::$view;
  238. $_view_type2 = $_view_config ['template_type'] === '' ? 'include' : $_view_config ['template_type'];
  239. $_view_show2 = $_view_show === null ? true : $_view_show;
  240. $_view_self2 = __CLASS__;
  241. // 视图模板处理
  242. switch ($_view_type2) {
  243. case 'include' :
  244. extract($_view_vars2);
  245. if ($_view_show2) {
  246. return require $_view_file2;
  247. } else {
  248. ob_start();
  249. require $_view_file2;
  250. return ob_get_clean();
  251. }
  252. case 'string' :
  253. extract($_view_vars2);
  254. if ($_view_show2) {
  255. return eval('echo <<<_END_OF_EVAL' . PHP_EOL . file_get_contents($_view_file2, FILE_USE_INCLUDE_PATH) . PHP_EOL . '_END_OF_EVAL;' . PHP_EOL);
  256. } else {
  257. return eval('return <<<_END_OF_EVAL' . PHP_EOL . file_get_contents($_view_file2, FILE_USE_INCLUDE_PATH) . PHP_EOL . '_END_OF_EVAL;' . PHP_EOL);
  258. }
  259. default :
  260. extract($_view_vars2);
  261. $_view_extension = self::_path_extension($_view_type2 . '.php');
  262. if (is_file($_view_extension)) {
  263. return require $_view_extension;
  264. } else {
  265. return;
  266. }
  267. }
  268. }
  269. /**
  270. * 数据库连接
  271. *
  272. * @link http://www.coremvc.cn/api/core/connect.php
  273. * @param mixed $args
  274. * @param array &$ref
  275. * @param array $info
  276. * @return $dbh
  277. */
  278. public static function connect($args = null, &$ref = null, $info = null) {
  279. // 导入配置文件
  280. $connect = &self::$connect;
  281. if (!is_array($connect)) {
  282. if (empty($connect)) {
  283. $connect = array();
  284. } else {
  285. $connect = self::_init_file($connect);
  286. if (!is_array($connect)) {
  287. $connect = array();
  288. }
  289. }
  290. $import_config = self::_init_env('connect');
  291. if ($import_config !== array()) {
  292. $connect = array_merge($connect, $import_config);
  293. }
  294. } elseif ($args === true && isset($connect ['current']) && isset($connect ['connections']) && isset($connect ['configs'] [$connect ['current']]) && isset($connect ['connections'] [$connect ['current']])) {
  295. // 返回当前连接
  296. $pos = $connect ['current'];
  297. $ref = $connect ['configs'] [$pos];
  298. $dbh = &$connect ['connections'] [$pos];
  299. switch ($ref ['connect_provider']) {
  300. // 【扩展功能】重连数据库
  301. default :
  302. $callback = array($ref ['connect_provider'], 'reconnect');
  303. if (!is_callable($callback)) {
  304. $provider_file = self::_path_extension($ref ['connect_provider'] . '.php');
  305. if (is_file($provider_file)) {
  306. require_once $provider_file;
  307. }
  308. }
  309. if (is_callable($callback)) {
  310. $dbh = call_user_func($callback, $dbh, $ref, $pos, $info);
  311. break;
  312. }
  313. case '' :
  314. case 'mysql' :
  315. if ($dbh === null || !mysql_ping($dbh)) {
  316. self::connect(false, $ref, $info);
  317. $dbh = self::connect(true, $ref, $info);
  318. }
  319. break;
  320. }
  321. return $dbh;
  322. }
  323. // 选择指定连接
  324. if (is_int($args)) {
  325. $connect ['current'] = $args;
  326. } elseif (!array_key_exists('current', $connect)) {
  327. $connect ['current'] = 0;
  328. } elseif (!is_int($connect ['current'])) {
  329. $connect ['current'] = (int) $connect ['current'];
  330. }
  331. $pos = $connect ['current'];
  332. if (!array_key_exists('configs', $connect) || !is_array($connect ['configs'])) {
  333. $connect ['configs'] = array();
  334. }
  335. if (!array_key_exists('connections', $connect) || !is_array($connect ['connections'])) {
  336. $connect ['connections'] = array();
  337. }
  338. if (!array_key_exists($pos, $connect ['configs']) || !is_array($connect ['configs'] [$pos])) {
  339. $connect ['configs'] [$pos] = array();
  340. }
  341. if (!array_key_exists($pos, $connect ['connections'])) {
  342. $connect ['connections'] [$pos] = null;
  343. }
  344. $cfg = &$connect ['configs'] [$pos];
  345. $dbh = &$connect ['connections'] [$pos];
  346. if (is_int($args)) {
  347. $ref = $cfg;
  348. return $dbh;
  349. }
  350. if ($args === null) {
  351. // 返回所有参数
  352. $ref = $cfg;
  353. return $connect;
  354. } elseif (is_array($args)) {
  355. // 设置参数配置
  356. foreach ($args as $key => $value) {
  357. $cfg [$key] = $value;
  358. }
  359. $ref = $cfg;
  360. return $dbh;
  361. } elseif (is_string($args)) {
  362. // 导入参数配置
  363. $ext = strtolower(strrchr($args, '.'));
  364. if (strtolower(strrchr($args, '.')) === '.php') {
  365. // 导入参数文件
  366. $import_config = self::_init_file($args);
  367. if ($import_config !== array()) {
  368. $cfg = array_merge($cfg, $import_config);
  369. }
  370. $ref = $cfg;
  371. return $dbh;
  372. } else {
  373. // 返回参数配置
  374. $ref = $cfg;
  375. return isset($cfg [$args]) ? $cfg [$args] : '';
  376. }
  377. }
  378. // 设置当前连接
  379. $config = self::init(false);
  380. $properties = array('connect_provider', 'connect_dsn', 'connect_type', 'connect_server', 'connect_username', 'connect_password',
  381. 'connect_new_link', 'connect_client_flags', 'connect_dbname', 'connect_charset', 'connect_port', 'connect_socket',
  382. 'connect_driver_options', 'prefix_search', 'prefix_replace', 'debug_enable', 'debug_file', 'sql_format');
  383. foreach ($properties as $property) {
  384. if (!isset($cfg [$property])) {
  385. if (isset($config [$property])) {
  386. $cfg [$property] = $config [$property];
  387. } else {
  388. $cfg [$property] = '';
  389. }
  390. }
  391. }
  392. $ref = $cfg;
  393. // 断开数据库
  394. if ($args === false) {
  395. switch ($ref ['connect_provider']) {
  396. // 【扩展功能】断开数据库
  397. default :
  398. $callback = array($ref ['connect_provider'], 'disconnect');
  399. if (!is_callable($callback)) {
  400. $provider_file = self::_path_extension($ref ['connect_provider'] . '.php');
  401. if (is_file($provider_file)) {
  402. require_once $provider_file;
  403. }
  404. }
  405. if (is_callable($callback)) {
  406. $return = call_user_func($callback, $dbh, $ref, $pos, $info);
  407. break;
  408. }
  409. case '' :
  410. case 'mysql' :
  411. if (is_resource($dbh) && get_resource_type($dbh) == 'mysql link') {
  412. $return = mysql_close($dbh);
  413. } else {
  414. $return = false;
  415. }
  416. break;
  417. }
  418. $ref = $cfg = array();
  419. $dbh = null;
  420. return $dbh;
  421. }
  422. // 连接数据库
  423. if ($args === true) {
  424. switch ($ref ['connect_provider']) {
  425. // 【扩展功能】连接数据库
  426. default :
  427. $callback = array($ref ['connect_provider'], 'connect');
  428. if (!is_callable($callback)) {
  429. $provider_file = self::_path_extension($ref ['connect_provider'] . '.php');
  430. if (is_file($provider_file)) {
  431. require_once $provider_file;
  432. }
  433. }
  434. if (is_callable($callback)) {
  435. $dbh = call_user_func($callback, $ref, $pos, $info);
  436. break;
  437. }
  438. case '' :
  439. case 'mysql' :
  440. $type = $ref ['connect_type'];
  441. $server = $ref ['connect_server'];
  442. $username = $ref ['connect_username'];
  443. $password = $ref ['connect_password'];
  444. $new_link = $ref ['connect_new_link'];
  445. $client_flags = $ref ['connect_client_flags'];
  446. $dbname = $ref ['connect_dbname'];
  447. $charset = $ref ['connect_charset'];
  448. if ($type === 'persist') {
  449. $dbh = mysql_pconnect($server, $username, $password, (int) $client_flags);
  450. } else {
  451. $dbh = mysql_connect($server, $username, $password, (bool) $new_link, (int) $client_flags);
  452. }
  453. if ($dbname) {
  454. mysql_select_db($dbname, $dbh);
  455. }
  456. if ($charset) {
  457. if (function_exists('mysql_set_charset')) {
  458. mysql_set_charset($charset, $dbh);
  459. } else {
  460. mysql_query('SET NAMES ' . $charset, $dbh);
  461. }
  462. }
  463. break;
  464. }
  465. return $dbh;
  466. }
  467. }
  468. /**
  469. * 执行SQL语句
  470. *
  471. * @link http://www.coremvc.cn/api/core/execute.php
  472. * @param string $sql
  473. * @param array $param
  474. * @param array &$ref
  475. * @return mixed
  476. */
  477. public static function execute($sql, $param = null, &$ref = null) {
  478. // 【基础功能】执行语句
  479. $ref_flag = (func_num_args() > 2);
  480. $dbh = self::connect(true, $args, array('execute', $sql, $param, $ref));
  481. if ($args ['prefix_search'] !== '' && $args ['prefix_search'] !== $args ['prefix_replace']) {
  482. $sql = str_replace($args ['prefix_search'], $args ['prefix_replace'], $sql);
  483. }
  484. switch ($args ['connect_provider']) {
  485. // 【扩展功能】执行语句
  486. default :
  487. $callback = array($provider = $args ['connect_provider'], 'execute');
  488. if (is_callable($callback)) {
  489. if ($ref_flag) {
  490. $result = call_user_func_array($callback, array($dbh, $args, __CLASS__, $sql, $param, &$ref));
  491. } else {
  492. $result = call_user_func_array($callback, array($dbh, $args, __CLASS__, $sql, $param));
  493. }
  494. break;
  495. }
  496. case '' :
  497. case 'mysql' :
  498. // 是否强制参数转SQL
  499. if (isset($args ['sql_format']) && $args ['sql_format']) {
  500. $sql = self::prepare($sql, $param, true);
  501. $param = null;
  502. }
  503. if (is_array($param)) {
  504. $stmt = 'coremvc_mysql_stmt';
  505. $var = '@coremvc_mysql_var';
  506. $sql_set = '';
  507. $sql_unset = '';
  508. $using = '';
  509. $key = 0;
  510. foreach ($param as $value) {
  511. if ($value === null) {
  512. $value = 'NULL';
  513. } elseif ($value === true) {
  514. $value = '1';
  515. } elseif ($value === false) {
  516. $value = '0';
  517. } elseif (is_int($value) || is_float($value)) {
  518. } else {
  519. $value = '\'' . mysqli_real_escape_string($dbh, (string) $value) . '\'';
  520. }
  521. $varname = $var . ++$key;
  522. if ($key === 1) {
  523. $sql_set = 'SET ' . $varname . '=' . $value;
  524. $sql_unset = 'SET ' . $varname . '=NULL';
  525. $using = ' USING ' . $varname;
  526. } else {
  527. $sql_set .= ',' . $varname . '=' . $value;
  528. $sql_unset .= ',' . $varname . '=NULL';
  529. $using .= ',' . $varname;
  530. }
  531. }
  532. mysql_query('PREPARE ' . $stmt . ' FROM \'' . mysqli_real_escape_string($dbh, $sql) . '\'', $dbh);
  533. if ($sql_set !== '') {
  534. mysql_query($sql_set, $dbh);
  535. }
  536. $result = mysql_query('EXECUTE ' . $stmt . $using, $dbh);
  537. } else {
  538. $result = mysql_query($sql, $dbh);
  539. }
  540. // 数据库调试开关
  541. if (isset($args ['debug_enable']) && $args ['debug_enable']) {
  542. if ($result === false) {
  543. $extra = array('errno' => mysql_errno($dbh), 'error' => mysql_error($dbh));
  544. } else {
  545. $extra = null;
  546. }
  547. self::prepare($sql, $param, null, true, $args ['debug_file'], $extra);
  548. }
  549. if ($ref_flag) {
  550. $ref = array();
  551. $ref ['insert_id'] = (string) mysql_insert_id($dbh);
  552. $ref ['affected_rows'] = max(mysql_affected_rows($dbh), 0);
  553. $ref ['num_fields'] = is_resource($result) ? mysql_num_fields($result) : 0;
  554. $ref ['num_rows'] = is_resource($result) ? mysql_num_rows($result) : 0;
  555. }
  556. if (is_array($param)) {
  557. if ($sql_unset !== '') {
  558. mysql_query($sql_unset, $dbh);
  559. }
  560. mysql_query('DEALLOCATE PREPARE ' . $stmt, $dbh);
  561. }
  562. break;
  563. }
  564. return $result;
  565. }
  566. /**
  567. * 准备SQL语句
  568. *
  569. * @link http://www.coremvc.cn/api/core/prepare.php
  570. * @param string $sql
  571. * @param array $param
  572. * @param bool $format
  573. * @param bool $debug
  574. * @param string $output
  575. * @param array $extra
  576. * @return mixed
  577. */
  578. public static function prepare($sql, $param = null, $format = null, $debug = null, $output = null, $extra = null) {
  579. // 【基础功能】准备SQL语句
  580. $mysql_escape_search = array("\\", "\x00", "\n", "\r", "'", "\"", "\x1a");
  581. $mysql_escape_replace = array("\\\\", "\\0", "\\n", "\\r", "\\'", "\\\"", "\\Z");
  582. if (strncmp($sql, 'mysql_escape_', 13) === 0) {
  583. $debug_provider = 'mysql';
  584. if ($format) {
  585. $return_sql = array();
  586. foreach ($param as $key => $value) {
  587. if ($value === array() || $key === 'page' && $sql === 'mysql_escape_other') {
  588. continue;
  589. }
  590. if (is_int($key)) {
  591. switch ($sql) {
  592. case 'mysql_escape_where' :
  593. case 'mysql_escape_where2' :
  594. if (is_array($value)) {
  595. $escape_sql = $sql === 'mysql_escape_where2' ? 'mysql_where' : 'mysql_where2';
  596. $return_sql [] = self::prepare($escape_sql, $value, true);
  597. break;
  598. }
  599. default :
  600. if ($value === null) {
  601. $value = 'NULL';
  602. } elseif ($value === true) {
  603. $value = '1';
  604. } elseif ($value === false) {
  605. $value = '0';
  606. } else {
  607. $value = (string) $value;
  608. }
  609. $return_sql [] = $value;
  610. break;
  611. }
  612. continue;
  613. }
  614. if (is_array($value)) {
  615. foreach ($value as &$value2) {
  616. if ($value2 === null) {
  617. $value2 = 'NULL';
  618. } elseif ($value2 === true) {
  619. $value2 = '1';
  620. } elseif ($value2 === false) {
  621. $value2 = '0';
  622. } elseif (is_int($value2) || is_float($value2)) {
  623. } else {
  624. $value2 = '\'' . str_replace($mysql_escape_search, $mysql_escape_replace, $value2) . '\'';
  625. }
  626. }
  627. } elseif ($value === null) {
  628. $value = 'NULL';
  629. } elseif ($value === true) {
  630. $value = '1';
  631. } elseif ($value === false) {
  632. $value = '0';
  633. } elseif (is_int($value) || is_float($value)) {
  634. } else {
  635. $value = '\'' . str_replace($mysql_escape_search, $mysql_escape_replace, $value) . '\'';
  636. }
  637. $pos = strpos($key, '?');
  638. if ($pos === false) {
  639. if (is_array($value)) {
  640. switch ($sql) {
  641. case 'mysql_escape_set' :
  642. $sep1 = $key . '=CONCAT_WS(\',\',';
  643. $sep2 = ')';
  644. break;
  645. default :
  646. case 'mysql_escape_value' :
  647. $sep1 = 'CONCAT_WS(\',\',';
  648. $sep2 = ')';
  649. break;
  650. case 'mysql_escape_where' :
  651. case 'mysql_escape_where2' :
  652. $sep1 = $key . ' IN (';
  653. $sep2 = ')';
  654. break;
  655. case 'mysql_escape_other' :
  656. $sep1 = $key . ' ';
  657. $sep2 = '';
  658. break;
  659. }
  660. $return_sql [] = $sep1 . implode(',', $value) . $sep2;
  661. } else {
  662. switch ($sql) {
  663. case 'mysql_escape_set' :
  664. case 'mysql_escape_where' :
  665. case 'mysql_escape_where2' :
  666. $sep = $key . '=';
  667. break;
  668. default :
  669. case 'mysql_escape_value' :
  670. $sep = '';
  671. break;
  672. case 'mysql_escape_other' :
  673. $sep = $key . ' ';
  674. break;
  675. }
  676. $return_sql [] = $sep . $value;
  677. }
  678. } else {
  679. if (is_array($value)) {
  680. $key = str_replace(array('%', '?'), array('%%', '%s'), $key);
  681. $return_sql [] = vsprintf($key, $value);
  682. } else {
  683. $return_sql [] = substr_replace($key, $value, $pos, 1);
  684. }
  685. }
  686. }
  687. $return = $return_sql;
  688. } else {
  689. $return_sql = array();
  690. $return_param = array();
  691. foreach ($param as $key => $value) {
  692. if ($value === array() || $key === 'page' && $sql === 'mysql_escape_other') {
  693. continue;
  694. }
  695. if (is_int($key)) {
  696. switch ($sql) {
  697. case 'mysql_escape_where' :
  698. case 'mysql_escape_where2' :
  699. if (is_array($value)) {
  700. $escape_sql = $sql === 'mysql_escape_where2' ? 'mysql_where' : 'mysql_where2';
  701. list ( $list_sql, $list_param ) = self::prepare($escape_sql, $value);
  702. $return_sql [] = $list_sql;
  703. foreach ($list_param as &$value2) {
  704. $return_param [] = $value2;
  705. }
  706. break;
  707. }
  708. default :
  709. if ($value === null) {
  710. $value = 'NULL';
  711. } elseif ($value === true) {
  712. $value = '1';
  713. } elseif ($value === false) {
  714. $value = '0';
  715. } else {
  716. $value = (string) $value;
  717. }
  718. $return_sql [] = $value;
  719. break;
  720. }
  721. continue;
  722. }
  723. $pos = strpos($key, '?');
  724. if ($pos === false) {
  725. if (is_array($value)) {
  726. switch ($sql) {
  727. case 'mysql_escape_set' :
  728. $sep1 = $key . '=CONCAT_WS(\',\',';
  729. $sep2 = ')';
  730. break;
  731. default :
  732. case 'mysql_escape_value' :
  733. $sep1 = 'CONCAT_WS(\',\',';
  734. $sep2 = ')';
  735. break;
  736. case 'mysql_escape_where' :
  737. case 'mysql_escape_where2' :
  738. $sep1 = $key . ' IN (';
  739. $sep2 = ')';
  740. break;
  741. case 'mysql_escape_other' :
  742. $sep1 = $key . ' ';
  743. $sep2 = '';
  744. break;
  745. }
  746. $return_sql [] = $sep1 . implode(',', array_fill(0, count($value), '?')) . $sep2;
  747. foreach ($value as &$value2) {
  748. $return_param [] = $value2;
  749. }
  750. } else {
  751. switch ($sql) {
  752. case 'mysql_escape_set' :
  753. case 'mysql_escape_where' :
  754. case 'mysql_escape_where2' :
  755. $sep = $key . '=';
  756. break;
  757. default :
  758. case 'mysql_escape_value' :
  759. $sep = '';
  760. break;
  761. case 'mysql_escape_other' :
  762. $sep = $key . ' ';
  763. break;
  764. }
  765. $return_sql [] = $sep . '?';
  766. $return_param [] = $value;
  767. }
  768. } else {
  769. if (is_array($value)) {
  770. $return_sql [] = $key;
  771. foreach ($value as &$value2) {
  772. $return_param [] = $value2;
  773. }
  774. } else {
  775. $return_sql [] = $key;
  776. $return_param [] = $value;
  777. }
  778. }
  779. }
  780. $return = array($return_sql, $return_param);
  781. }
  782. } else {
  783. if (strncmp($sql, 'mysql_', 6) === 0) {
  784. $mysql = $sql;
  785. $sql = substr($sql, 6);
  786. $debug_provider = 'mysql';
  787. } else {
  788. $dbh = self::connect(true, $args, array('prepare', $sql, $param, $format, $debug, $output, $extra));
  789. switch ($args ['connect_provider']) {
  790. case '' :
  791. $mysql = 'mysql_' . $sql;
  792. $debug_provider = 'mysql';
  793. break;
  794. case 'mysql' :
  795. $mysql = 'mysql_' . $sql;
  796. $debug_provider = 'mysql';
  797. break;
  798. default :
  799. $mysql = false;
  800. $debug_provider = $args ['connect_provider'];
  801. break;
  802. }
  803. }
  804. switch ($mysql) {
  805. case 'mysql_selects' :
  806. isset($param [0]) or $param [0] = null;
  807. isset($param [1]) or $param [1] = null;
  808. isset($param [2]) or $param [2] = null;
  809. isset($param [3]) or $param [3] = null;
  810. if ($format) {
  811. $field_sql = self::prepare('mysql_field', $param [0], true);
  812. $table_sql = self::prepare('mysql_table', $param [1], true);
  813. $where_sql = self::prepare('mysql_where', $param [2], true);
  814. $other_sql = self::prepare('mysql_other', $param [3], true);
  815. if ($field_sql === '') {
  816. $field_sql = '*';
  817. }
  818. if ($table_sql === '') {
  819. $return_sql = "SELECT $field_sql $other_sql";
  820. } elseif ($where_sql === '') {
  821. $return_sql = "SELECT $field_sql FROM $table_sql $other_sql";
  822. } else {
  823. $return_sql = "SELECT $field_sql FROM $table_sql WHERE $where_sql $other_sql";
  824. }
  825. $return = rtrim($return_sql);
  826. } else {
  827. list ( $field_sql, $field_param ) = self::prepare('field', $param [0]);
  828. list ( $table_sql, $table_param ) = self::prepare('table', $param [1]);
  829. list ( $where_sql, $where_param ) = self::prepare('where', $param [2]);
  830. list ( $other_sql, $other_param ) = self::prepare('other', $param [3]);
  831. if ($field_sql === '') {
  832. $field_sql = '*';
  833. }
  834. if ($table_sql === '') {
  835. $return_sql = "SELECT $field_sql $other_sql";
  836. $return_param = array_merge($field_param, $other_param);
  837. } elseif ($where_sql === '') {
  838. $return_sql = "SELECT $field_sql FROM $table_sql $other_sql";
  839. $return_param = array_merge($field_param, $table_param, $other_param);
  840. } else {
  841. $return_sql = "SELECT $field_sql FROM $table_sql WHERE $where_sql $other_sql";
  842. $return_param = array_merge($field_param, $table_param, $where_param, $other_param);
  843. }
  844. $return = array(rtrim($return_sql), $return_param);
  845. }
  846. break;
  847. case 'mysql_inserts' :
  848. case 'mysql_replaces' :
  849. isset($param [0]) or $param [0] = null;
  850. isset($param [1]) or $param [1] = null;
  851. isset($param [2]) or $param [2] = null;
  852. isset($param [3]) or $param [3] = null;
  853. $mysql_sql = strtoupper(substr(substr($mysql, 6), 0, - 1));
  854. if ($format) {
  855. $table_sql = self::prepare('mysql_table', $param [0], true);
  856. $other_sql = self::prepare('mysql_other', $param [3], true);
  857. if (isset($param [2])) {
  858. $column_sql = self::prepare('mysql_column', $param [1], true);
  859. $value_sql = self::prepare('mysql_value', $param [2], true);
  860. $return_sql = "$mysql_sql $table_sql $column_sql VALUES $value_sql $other_sql";
  861. } elseif (is_array($param [1]) && count($param [1]) > 0 && !isset($param [1] [count($param [1]) - 1])) {
  862. $set_sql = self::prepare('mysql_set', $param [1], true);
  863. $return_sql = "$mysql_sql $table_sql SET $set_sql $other_sql";
  864. } else {
  865. $column_sql = self::prepare('mysql_column', $param [1], true);
  866. $return_sql = "$mysql_sql $table_sql $column_sql $other_sql";
  867. }
  868. $return = rtrim($return_sql);
  869. } else {
  870. list ( $table_sql, $table_param ) = self::prepare('mysql_table', $param [0]);
  871. list ( $other_sql, $other_param ) = self::prepare('mysql_other', $param [3]);
  872. if (isset($param [2])) {
  873. list ( $column_sql, $column_param ) = self::prepare('mysql_column', $param [1]);
  874. list ( $value_sql, $value_param ) = self::prepare('mysql_value', $param [2]);
  875. $return_sql = "$mysql_sql $table_sql $column_sql VALUES $value_sql $other_sql";
  876. $return_param = array_merge($table_param, $column_param, $value_param, $other_param);
  877. } elseif (is_array($param [1]) && count($param [1]) > 0 && !isset($param [1] [count($param [1]) - 1])) {
  878. list ( $set_sql, $set_param ) = self::prepare('mysql_set', $param [1]);
  879. $return_sql = "$mysql_sql $table_sql SET $set_sql $other_sql";
  880. $return_param = array_merge($table_param, $set_param, $other_param);
  881. } else {
  882. list ( $column_sql, $column_param ) = self::prepare('mysql_column', $param [1]);
  883. $return_sql = "$mysql_sql $table_sql $column_sql $other_sql";
  884. $return_param = array_merge($table_param, $column_param, $other_param);
  885. }
  886. $return = array(rtrim($return_sql), $return_param);
  887. }
  888. break;
  889. case 'mysql_updates' :
  890. isset($param [0]) or $param [0] = null;
  891. isset($param [1]) or $param [1] = null;
  892. isset($param [2]) or $param [2] = null;
  893. isset($param [3]) or $param [3] = null;
  894. if ($format) {
  895. $table_sql = self::prepare('mysql_table', $param [0], true);
  896. $set_sql = self::prepare('mysql_set', $param [1], true);
  897. $where_sql = self::prepare('mysql_where', $param [2], true);
  898. $other_sql = self::prepare('mysql_other', $param [3], true);
  899. if ($where_sql === '') {
  900. $return_sql = "UPDATE $table_sql SET $set_sql $other_sql";
  901. } else {
  902. $return_sql = "UPDATE $table_sql SET $set_sql WHERE $where_sql $other_sql";
  903. }
  904. $return = rtrim($return_sql);
  905. } else {
  906. list ( $table_sql, $table_param ) = self::prepare('mysql_table', $param [0]);
  907. list ( $set_sql, $set_param ) = self::prepare('mysql_set', $param [1]);
  908. list ( $where_sql, $where_param ) = self::prepare('mysql_where', $param [2]);
  909. list ( $other_sql, $other_param ) = self::prepare('mysql_other', $param [3]);
  910. if ($where_sql === '') {
  911. $return_sql = "UPDATE $table_sql SET $set_sql $other_sql";
  912. $return_param = array_merge($table_param, $set_param, $other_param);
  913. } else {
  914. $return_sql = "UPDATE $table_sql SET $set_sql WHERE $where_sql $other_sql";
  915. $return_param = array_merge($table_param, $set_param, $where_param, $other_param);
  916. }
  917. $return = array(rtrim($return_sql), $return_param);
  918. }
  919. break;
  920. case 'mysql_deletes' :
  921. isset($param [0]) or $param [0] = null;
  922. isset($param [1]) or $param [1] = null;
  923. isset($param [2]) or $param [2] = null;
  924. isset($param [3]) or $param [3] = null;
  925. if ($format) {
  926. $field_sql = self::prepare('mysql_field', $param [0], true);
  927. $table_sql = self::prepare('mysql_table', $param [1], true);
  928. $where_sql = self::prepare('mysql_where', $param [2], true);
  929. $other_sql = self::prepare('mysql_other', $param [3], true);
  930. if ($where_sql === '') {
  931. $return_sql = "DELETE $field_sql FROM $table_sql $other_sql";
  932. } else {
  933. $return_sql = "DELETE $field_sql FROM $table_sql WHERE $where_sql $other_sql";
  934. }
  935. $return = rtrim($return_sql);
  936. } else {
  937. list ( $field_sql, $field_param ) = self::prepare('mysql_field', $param [0]);
  938. list ( $table_sql, $table_param ) = self::prepare('mysql_table', $param [1]);
  939. list ( $where_sql, $where_param ) = self::prepare('mysql_where', $param [2]);
  940. list ( $other_sql, $other_param ) = self::prepare('mysql_other', $param [3]);
  941. if ($where_sql === '') {
  942. $return_sql = "DELETE $field_sql FROM $table_sql $other_sql";
  943. $return_param = array_merge($field_param, $table_param, $other_param);
  944. } else {
  945. $return_sql = "DELETE $field_sql FROM $table_sql WHERE $where_sql $other_sql";
  946. $return_param = array_merge($field_param, $table_param, $where_param, $other_param);
  947. }
  948. $return = array(rtrim($return_sql), $return_param);
  949. }
  950. break;
  951. case 'mysql_column' :
  952. if (is_array($param)) {
  953. $return_sql = '';
  954. $expect = '';
  955. foreach ($param as $key => $value) {
  956. if ($value === null) {
  957. $value = 'NULL';
  958. } elseif ($value === true) {
  959. $value = '1';
  960. } elseif ($value === false) {
  961. $value = '0';
  962. } else {
  963. $value = (string) $value;
  964. }
  965. $return_sql .= $expect . $value;
  966. $expect = ',';
  967. }
  968. } else {
  969. $return_sql = (string) $param;
  970. }
  971. if ($return_sql !== '') {
  972. $return_sql = '(' . $return_sql . ')';
  973. }
  974. $return = $format ? $return_sql : array($return_sql, array());
  975. break;
  976. case 'mysql_field' :
  977. case 'mysql_table' :
  978. if (is_array($param)) {
  979. $return_sql = '';
  980. $expect = '';
  981. foreach ($param as $key => $value) {
  982. if (is_array($value)) {
  983. foreach ($value as $value2) {
  984. if ($value2 === null) {
  985. $value2 = 'NULL';
  986. } elseif ($value2 === true) {
  987. $value2 = '1';
  988. } elseif ($value2 === false) {
  989. $value2 = '0';
  990. } else {
  991. $value2 = (string) $value2;
  992. }
  993. $return_sql .= $expect . $value2;
  994. $expect = ' ';
  995. }
  996. } else {
  997. if ($value === null) {
  998. $value = 'NULL';
  999. } elseif ($value === true) {
  1000. $value = '1';
  1001. } elseif ($value === false) {
  1002. $value = '0';
  1003. } else {
  1004. $value = (string) $value;
  1005. }
  1006. if (is_int($key)) {
  1007. $return_sql .= $expect . $value;
  1008. } else {
  1009. $return_sql .= $expect . $value . ' AS ' . $key;
  1010. }
  1011. $expect = ',';
  1012. }
  1013. }
  1014. } else {
  1015. $return_sql = (string) $param;
  1016. }
  1017. $return = $format ? $return_sql : array($return_sql, array());
  1018. break;
  1019. case 'mysql_set' :
  1020. case 'mysql_other' :
  1021. $escape_sql = substr_replace($mysql, 'escape_', 6, 0);
  1022. if (is_array($param)) {
  1023. if ($format) {
  1024. $return_sql = implode(',', self::prepare($escape_sql, $param, true));
  1025. } else {
  1026. list ( $return_sql, $return_param ) = self::prepare($escape_sql, $param);
  1027. $return_sql = implode(',', $return_sql);
  1028. }
  1029. } else {
  1030. $return_sql = (string) $param;
  1031. $return_param = array();
  1032. }
  1033. $return = $format ? $return_sql : array($return_sql, $return_param);
  1034. break;
  1035. case 'mysql_where' :
  1036. case 'mysql_where2' :
  1037. $escape_sql = substr_replace($mysql, 'escape_', 6, 0);
  1038. $escape_sep = $mysql === 'mysql_where2' ? ' OR ' : ' AND ';
  1039. if (is_array($param)) {
  1040. if ($format) {
  1041. $return_sql = implode($escape_sep, self::prepare($escape_sql, $param, true));
  1042. } else {
  1043. list ( $return_sql, $return_param ) = self::prepare($escape_sql, $param);
  1044. $return_sql = implode($escape_sep, $return_sql);
  1045. }
  1046. } else {
  1047. $return_sql = (string) $param;
  1048. $return_param = array();
  1049. }
  1050. if ($mysql === 'mysql_where2' && $return_sql !== '') {
  1051. $return_sql = '(' . $return_sql . ')';
  1052. }
  1053. $return = $format ? $return_sql : array($return_sql, $return_param);
  1054. break;
  1055. case 'mysql_value' :
  1056. if (is_array($param)) {
  1057. if (isset($param [0]) && is_array($param [0])) {
  1058. $return_sql = '';
  1059. $return_param = array();
  1060. $expect = '';
  1061. foreach ($param as $key => $value) {
  1062. if ($format) {
  1063. $value_sql = implode(',', self::prepare('mysql_escape_value', $value, true));
  1064. } else {
  1065. list ( $value_sql, $value_param ) = self::prepare('mysql_escape_value', $value);
  1066. $value_sql = implode(',', $value_sql);
  1067. foreach ($value_param as $value_value) {
  1068. $return_param [] = $value_value;
  1069. }
  1070. }
  1071. if ($value_sql !== '') {
  1072. $return_sql .= $expect . '(' . $value_sql . ')';
  1073. $expect = ',';
  1074. }
  1075. }
  1076. } else {
  1077. if ($format) {
  1078. $return_sql = implode(',', self::prepare('mysql_escape_value', $param, true));
  1079. } else {
  1080. list ( $return_sql, $return_param ) = self::prepare('mysql_escape_value', $param);
  1081. $return_sql = implode(',', $return_sql);
  1082. }
  1083. if ($return_sql !== '') {
  1084. $return_sql = '(' . $return_sql . ')';
  1085. }
  1086. }
  1087. } else {
  1088. $return_sql = (string) $param;
  1089. $return_param = array();
  1090. if ($return_sql !== '') {
  1091. $return_sql = '(' . $return_sql . ')';
  1092. }
  1093. }
  1094. $return = $format ? $return_sql : array($return_sql, $return_param);
  1095. break;
  1096. case false :
  1097. // 【扩展功能】准备SQL语句
  1098. $callback = array($args ['connect_provider'], 'prepare');
  1099. if (!is_callable($callback)) {
  1100. $provider_file = self::_path_extension($args ['connect_provider'] . '.php');
  1101. if (is_file($provider_file)) {
  1102. require_once $provider_file;
  1103. }
  1104. }
  1105. if ($args ['prefix_search'] !== '' && $args ['prefix_search'] !== $args ['prefix_replace']) {
  1106. $sql = str_replace($args ['prefix_search'], $args ['prefix_replace'], $sql);
  1107. }
  1108. if (is_callable($callback)) {
  1109. $return = call_user_func($callback, $dbh, $args, __CLASS__, $sql, $param, $format);
  1110. } else {
  1111. $return = self::prepare('mysql_' . $sql, $param, $format);
  1112. }
  1113. break;
  1114. default :
  1115. if ($format) {
  1116. $return_sql = str_replace(array('%', '?'), array('%%', '%s'), $sql);
  1117. if (is_array($param)) {
  1118. $return_param = $param;
  1119. foreach ($return_param as &$value) {
  1120. if ($value === null) {
  1121. $value = 'NULL';
  1122. } elseif ($value === true) {
  1123. $value = '1';
  1124. } elseif ($value === false) {
  1125. $value = '0';
  1126. } elseif (is_int($value) || is_float($value)) {
  1127. } else {
  1128. $value = '\'' . str_replace($mysql_escape_search, $mysql_escape_replace, $value) . '\'';
  1129. }
  1130. }
  1131. $return_sql = vsprintf($return_sql, $return_param);
  1132. }
  1133. $return = $return_sql;
  1134. } else {
  1135. $return = array($sql, $param);
  1136. }
  1137. break;
  1138. }
  1139. }
  1140. // 【基础功能】调试SQL语句
  1141. if ($debug) {
  1142. if ($format) {
  1143. $debug_sql = $return;
  1144. $debug_param = null;
  1145. } else {
  1146. list($debug_sql, $debug_param) = $return;
  1147. }
  1148. $echo2 = null;
  1149. if (is_array($debug_param)) {
  1150. $i = 0;
  1151. $echo2 = '';
  1152. foreach ($debug_param as $value) {
  1153. $echo2 .= PHP_EOL . '#' . ($i++) . ': ';
  1154. if ($value === null) {
  1155. $echo2 .= 'NULL';
  1156. } elseif ($value === true) {
  1157. $echo2 .= 'bool(true)';
  1158. } elseif ($value === false) {
  1159. $echo2 .= 'bool(false)';
  1160. } elseif (is_int($value)) {
  1161. $echo2 .= 'int(' . $value . ')';
  1162. } elseif (is_float($value)) {
  1163. $echo2 .= 'float(' . $value . ')';
  1164. } else {
  1165. $echo2 .= 'string(' . strlen($value) . ') ' . $value;
  1166. }
  1167. }
  1168. }
  1169. if (PHP_SAPI == 'cli' || !empty($output)) {
  1170. $echo = PHP_EOL . '(' . $debug_provider . '): ' . $debug_sql;
  1171. if (!empty($echo2)) {
  1172. $echo .= $echo2;
  1173. }
  1174. $echo .= PHP_EOL;
  1175. if (!empty($extra['errno'])) {
  1176. $echo .= $extra['errno'] . ": " . $extra['error'] . PHP_EOL;
  1177. }
  1178. } else {
  1179. $echo = PHP_EOL . '<hr />' . PHP_EOL . '(' . $debug_provider . '): ' . htmlentities($debug_sql) . PHP_EOL;
  1180. if (!empty($echo2)) {
  1181. $echo .= str_replace(PHP_EOL, '<br />' . PHP_EOL, htmlentities($echo2));
  1182. }
  1183. $echo .= '<hr />' . PHP_EOL;
  1184. if (!empty($extra['errno'])) {
  1185. $echo .= $extra['errno'] . ": " . htmlentities($extra['error']) . '<br />' . PHP_EOL;
  1186. }
  1187. }
  1188. if (empty($output)) {
  1189. echo $echo;
  1190. } else {
  1191. file_put_contents(self::path($output), $echo, FILE_APPEND);
  1192. }
  1193. }
  1194. return $return;
  1195. }
  1196. /**
  1197. * 生成自增序列(可继承)
  1198. *
  1199. * @link http://www.coremvc.cn/api/core/sequence.php
  1200. * @param string $tablename
  1201. * @param int $start_index
  1202. * @return int
  1203. */
  1204. public static function sequence($tablename = 'sequence', $start_index = 1) {
  1205. // 【基础功能】生成自增序列
  1206. $dbh = self::connect(true, $args, array('sequence', $tablename, $start_index));
  1207. // 表名
  1208. if ($args ['prefix_search'] !== '' && $args ['prefix_search'] !== $args ['prefix_replace']) {
  1209. $tablename = str_replace($args ['prefix_search'], $args ['prefix_replace'], $tablename);
  1210. }
  1211. // 执行
  1212. switch ($args ['connect_provider']) {
  1213. // 【扩展功能】生成自增序列
  1214. default :
  1215. $callback = array($args ['connect_provider'], 'sequence');
  1216. if (is_callable($callback)) {
  1217. $return = call_user_func($callback, $dbh, $args, __CLASS__, $tablename, $start_index);
  1218. break;
  1219. }
  1220. case '' :
  1221. case 'mysql' :
  1222. $result = mysql_query('UPDATE ' . $tablename . ' SET id=LAST_INSERT_ID(id+1)', $dbh);
  1223. if ($result === false) {
  1224. mysql_query('CREATE TABLE ' . $tablename . ' (id INT NOT NULL)', $dbh);
  1225. $rs = mysql_query('SELECT COUNT(*) FROM ' . $tablename . ' LIMIT 1', $dbh);
  1226. if (mysql_result($rs, 0) == 0) {
  1227. mysql_query('INSERT INTO ' . $tablename . ' VALUES (' . ($start_index - 1) . ')', $dbh);
  1228. }
  1229. mysql_query('UPDATE ' . $tablename . ' SET id=LAST_INSERT_ID(id+1)', $dbh);
  1230. }
  1231. $return = mysql_insert_id($dbh);
  1232. if ($return === false) {
  1233. return false;
  1234. }
  1235. if ($start_index > $return) {
  1236. mysql_query('UPDATE ' . $tablename . ' SET id=' . $start_index, $dbh);
  1237. $return = $start_index;
  1238. }
  1239. break;
  1240. }
  1241. return $return;
  1242. }
  1243. /**
  1244. * 静态构造函数(可继承)
  1245. *
  1246. * @link http://www.coremvc.cn/api/core/structs.php
  1247. * @param array $array
  1248. * @param mixed $struct
  1249. * @return array
  1250. */
  1251. public static function structs($array = null, $struct = null) {
  1252. // 【基础功能】构造对象数组
  1253. // 数组
  1254. if ($array === null || $array === '') {
  1255. $data_arr = array(null);
  1256. } elseif (is_object($array)) {
  1257. $data_arr = array($array);
  1258. } elseif (is_array($array)) {
  1259. $data_arr = $array;
  1260. } else {
  1261. return;
  1262. }
  1263. // 类名
  1264. if ($struct === null || $struct === '') {
  1265. $class_arr = array(null, 'class' => null);
  1266. } elseif (is_string($struct)) {
  1267. $class_arr = array(null, 'class' => $struct);
  1268. } elseif (is_object($struct)) {
  1269. $class_arr = array(null, 'clone' => $struct);
  1270. } elseif (is_array($struct)) {
  1271. if ($struct === array()) {
  1272. return;
  1273. }
  1274. $class_arr = $struct;
  1275. } else {
  1276. return;
  1277. }
  1278. foreach ($class_arr as $classkey => $classname) {
  1279. }
  1280. unset($class_arr [$classkey]);
  1281. if (is_int($classkey)) {
  1282. if ($classname === null || $classname === '') {
  1283. $classkey = 'class';
  1284. } elseif (is_int($classname)) {
  1285. $classkey = 'column';
  1286. } elseif (is_string($classname)) {
  1287. $classkey = 'column';
  1288. } elseif (is_object($classname)) {
  1289. $classkey = 'clone';
  1290. } elseif (is_array($classname)) {
  1291. $classkey = 'array';
  1292. } else {
  1293. return;
  1294. }
  1295. }
  1296. if (function_exists('get_called_class')) {
  1297. $calledclass = get_called_class();
  1298. } else {
  1299. $calledclass = __CLASS__;
  1300. }
  1301. // 整理
  1302. $return = array();
  1303. foreach ($data_arr as $data) {
  1304. $data_str = array();
  1305. $data_int = array();
  1306. $data_all = array();
  1307. if (is_object($data) || is_array($data)) {
  1308. $int2 = 0;
  1309. foreach ($data as $key2 => $data2) {
  1310. if (is_int($key2)) {
  1311. $data_int [$key2] = $data2;
  1312. continue;
  1313. }
  1314. $data_str [$key2] = $data2;
  1315. $data_int [$int2] = $data2;
  1316. $data_all [$key2] = $data2;
  1317. $data_all [$int2] = $data2;
  1318. $int2++;
  1319. }
  1320. }
  1321. $point1 = &$return;
  1322. foreach ($class_arr as $class) {
  1323. $point2 = array();
  1324. if ($class === null || $class === '') {
  1325. $point1 [] = &$point2;
  1326. } else {
  1327. if (is_int($class) && isset($data_int [$class])) {
  1328. $point3 = $data_int [$class];
  1329. } elseif (is_string($class) && isset($data_str [$class])) {
  1330. $point3 = $data_str [$class];
  1331. } else {
  1332. $point3 = '';
  1333. }
  1334. if (isset($point1 [$point3])) {
  1335. $point2 = &$point1 [$point3];
  1336. } else {
  1337. $point1 [$point3] = &$point2;
  1338. }
  1339. }
  1340. unset($point1);
  1341. $point1 = &$point2;
  1342. unset($point2);
  1343. }
  1344. switch ($classkey) {
  1345. case 'assoc' :
  1346. $point1 = $data_str;
  1347. break;
  1348. case 'num' :
  1349. $point1 = $data_int;
  1350. break;
  1351. case 'both' :
  1352. $point1 = $data_all;
  1353. break;
  1354. case 'array' :
  1355. if (is_array($classname)) {
  1356. $point1 = $classname;
  1357. foreach ($data_str as $key => $value) {
  1358. if (array_key_exists($key, $point1)) {
  1359. $point1 [$key] = $value;
  1360. }
  1361. }
  1362. foreach ($data_int as $key => $value) {
  1363. if (array_key_exists($key, $point1)) {
  1364. $point1 [$key] = $value;
  1365. }
  1366. }
  1367. } else {
  1368. $point1 = array();
  1369. }
  1370. break;
  1371. case 'column' :
  1372. if (is_int($classname) && isset($data_int [$classname])) {
  1373. $point1 = $data_int [$classname];
  1374. } elseif (is_string($classname) && isset($data_str [$classname])) {
  1375. $point1 = $data_str [$classname];
  1376. } else {
  1377. $point1 = null;
  1378. }
  1379. break;
  1380. default :
  1381. case 'class' :
  1382. if (class_exists($classname)) {
  1383. $point1 = new $classname ( );
  1384. } else {
  1385. $point1 = new $calledclass ( );
  1386. }
  1387. foreach ($data_str as $key => $value) {
  1388. $point1->$key = $value;
  1389. }
  1390. break;
  1391. case 'class|classtype' :
  1392. $i = 0;
  1393. foreach ($data_str as $key => $value) {
  1394. if ($i++ === 0) {
  1395. if (isset($data_int [0]) && preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/', $data_int [0]) && class_exists($data_int [0])) {
  1396. $point1 = new $data_int [0] ( );
  1397. } elseif (class_exists($classname)) {
  1398. $point1 = new $classname ( );
  1399. } else {
  1400. $point1 = new $calledclass ( );
  1401. }
  1402. continue;
  1403. }
  1404. $point1->$key = $value;
  1405. }
  1406. if ($i === 0) {
  1407. if (isset($data_int [0]) && preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/', $data_int [0]) && class_exists($data_int [0])) {
  1408. $point1 = new $data_int [0] ( );
  1409. } elseif (class_exists($classname)) {
  1410. $point1 = new $classname ( );
  1411. } else {
  1412. $point1 = new $calledclass ( );
  1413. }
  1414. }
  1415. break;
  1416. case 'clone' :
  1417. if (is_object($classname)) {
  1418. $point1 = clone $classname;
  1419. } else {
  1420. $point1 = new $calledclass ( );
  1421. }
  1422. foreach ($data_str as $key => $value) {
  1423. $point1->$key = $value;
  1424. }
  1425. break;
  1426. }
  1427. }
  1428. return $return;
  1429. }
  1430. /**
  1431. * 静态选择函数(可继承)
  1432. *
  1433. * @link http://www.coremvc.cn/api/core/selects.php
  1434. * @param mixed $field_sql
  1435. * @param mixed $table_param
  1436. * @param mixed $where_bool
  1437. * @param mixed $other
  1438. * @param mixed $struct
  1439. * @return array
  1440. */
  1441. public static function selects($field_sql = null, $table_param = null, $where_bool = null, $other = null, $struct = null) {
  1442. // 【基础功能】静态选择数据
  1443. $dbh = self::connect(true, $args, array('selects', $field_sql, $table_param, $where_bool, $other, $struct));
  1444. // 类名
  1445. if ($struct === null || $struct === '') {
  1446. $class_arr = array(null, 'class' => null);
  1447. } elseif (is_string($struct)) {
  1448. $class_arr = array(null, 'class' => $struct);
  1449. } elseif (is_object($struct)) {
  1450. $class_arr = array(null, 'clone' => $struct);
  1451. } elseif (is_array($struct)) {
  1452. if ($struct === array()) {
  1453. return;
  1454. }
  1455. $class_arr = $struct;
  1456. } else {
  1457. return;
  1458. }
  1459. foreach ($class_arr as $classkey => $classname) {
  1460. }
  1461. unset($class_arr [$classkey]);
  1462. if (is_int($classkey)) {
  1463. if ($classname === null || $classname === '') {
  1464. $classkey = 'class';
  1465. } elseif (is_int($classname)) {
  1466. $classkey = 'column';
  1467. } elseif (is_string($classname)) {
  1468. $classkey = 'column';
  1469. } elseif (is_object($classname)) {
  1470. $classkey = 'clone';
  1471. } elseif (is_array($classname)) {
  1472. $classkey = 'array';
  1473. } else {
  1474. return;
  1475. }
  1476. }
  1477. if (function_exists('get_called_class')) {
  1478. $calledclass = get_called_class();
  1479. } else {
  1480. $calledclass = __CLASS__;
  1481. }
  1482. $classkey_arr = null;
  1483. if (strpos($classkey, '|') !== false) {
  1484. $classkey_arr = explode('|', $classkey);
  1485. $classkey = array_shift($classkey_arr);
  1486. foreach ($classkey_arr as $classkey_key) {
  1487. if (strncmp($classkey_key, 'table=', 6) === 0) {
  1488. $table_class = substr($classkey_key, 6);
  1489. if ($table_class === '') {
  1490. $table_class = $calledclass;
  1491. }
  1492. }
  1493. }
  1494. }
  1495. // 参数
  1496. if (is_bool($where_bool)) {
  1497. $sql = $field_sql;
  1498. $param = is_array($table_param) ? $table_param : array();
  1499. } else {
  1500. if ($table_param === null) {
  1501. if (isset($table_class)) {
  1502. } elseif (is_string($classname)) {
  1503. if (class_exists($classname)) {
  1504. $table_class = $classname;
  1505. } else {
  1506. $table_class = $calledclass;
  1507. }
  1508. } elseif (is_object($classname)) {
  1509. $table_class = get_class($classname);
  1510. } else {
  1511. $table_class = $calledclass;
  1512. }
  1513. if ($args ['prefix_search'] === '') {
  1514. $table = $table_class;
  1515. } else {
  1516. $table = $args ['prefix_search'] . $table_class;
  1517. }
  1518. } else {
  1519. $table = $table_param;
  1520. }
  1521. $field = $field_sql;
  1522. $where = $where_bool;
  1523. list ( $sql, $param ) = self::prepare('selects', array($field, $table, $where, $other));
  1524. }
  1525. // 分页
  1526. if (is_array($other) && isset($other ['page'])) {
  1527. $page = &$other ['page'];
  1528. if (is_array($page)) {
  1529. if (isset($page ['page'])) {
  1530. settype($page ['page'], 'int');
  1531. if ($page ['page'] < 1) {
  1532. $page ['page'] = 1;
  1533. }
  1534. } else {
  1535. $page ['page'] = 1;
  1536. }
  1537. if (isset($page ['size'])) {
  1538. settype($page ['size'], 'int');
  1539. if ($page ['size'] < 1) {
  1540. $page ['size'] = 1;
  1541. }
  1542. } else {
  1543. $page ['size'] = 1;
  1544. }
  1545. if (isset($page ['count'])) {
  1546. settype($page ['count'], 'int');
  1547. if ($page ['count'] < 0) {
  1548. $page ['count'] = null;
  1549. }
  1550. } else {
  1551. $page ['count'] = null;
  1552. }
  1553. if (isset($page ['total'])) {
  1554. settype($page ['total'], 'int');
  1555. if ($page ['total'] < 0) {
  1556. $page ['total'] = null;
  1557. }
  1558. } else {
  1559. $page ['total'] = null;
  1560. }
  1561. } else {
  1562. $page = array('page' => 1, 'size' => 1, 'count' => null, 'total' => null);
  1563. }
  1564. } else {
  1565. $page = null;
  1566. }
  1567. // 执行
  1568. switch ($args ['connect_provider']) {
  1569. // 【扩展功能】静态选择数据
  1570. default :
  1571. $callback = array($args ['connect_provider'], 'selects');
  1572. if (is_callable($callback)) {
  1573. if ($args ['prefix_search'] !== '' && $args ['prefix_search'] !== $args ['prefix_replace']) {
  1574. $sql = str_replace($args ['prefix_search'], $args ['prefix_replace'], $sql);
  1575. }
  1576. $ref = array('page' => &$page, 'class_arr' => $class_arr, 'classkey' => $classkey, 'classkey_arr' => $classkey_arr, 'classname' => $classname, 'calledclass' => $calledclass);
  1577. list ( $data_arr, $data_all ) = call_user_func($callback, $dbh, $args, __CLASS__, $sql, $param, $ref);
  1578. break;
  1579. }
  1580. case '' :
  1581. case 'mysql' :
  1582. if ($page !== null) {
  1583. if ($page ['count'] === null) {
  1584. $sql = preg_replace('/SELECT/i', 'SELECT SQL_CALC_FOUND_ROWS', $sql, 1);
  1585. }
  1586. $limit = 'LIMIT ' . ($page ['size'] * ($page ['page'] - 1)) . ',' . $page ['size'];
  1587. if (isset($page ['limit'])) {
  1588. $sql = preg_replace('/(.*)' . $page ['limit'] . '/i', '$1' . $limit, $sql, 1);
  1589. } else {
  1590. $sql .= ' ' . $limit;
  1591. }
  1592. }
  1593. $data_key = array();
  1594. foreach ($class_arr as $value) {
  1595. if ($value !== null && $value !== '' && !in_array($value, $data_key, true)) {
  1596. $data_key [] = $value;
  1597. }
  1598. }
  1599. $result = self::execute($sql, $param);
  1600. if ($result === false) {
  1601. return false;
  1602. }
  1603. if ($page !== null) {
  1604. if ($page ['count'] === null) {
  1605. list ( $page ['count'] ) = mysql_fetch_row(mysql_unbuffered_query('SELECT FOUND_ROWS()', $dbh));
  1606. }
  1607. $page ['total'] = (int) ceil($page ['count'] / $page ['size']);
  1608. }
  1609. // 数据
  1610. if (!is_resource($result) || mysql_num_rows($result) === 0) {
  1611. $data_arr = array();
  1612. break;
  1613. }
  1614. $data_all = array();
  1615. if ($data_key !== array()) {
  1616. while ($obj = mysql_fetch_array($result)) {
  1617. $obj_arr = array();
  1618. foreach ($data_key as $value) {
  1619. if (array_key_exists($value, $obj)) {
  1620. $obj_arr [$value] = $obj [$value];
  1621. }
  1622. }
  1623. $data_all [] = $obj_arr;
  1624. }
  1625. mysql_data_seek($result, 0);
  1626. }
  1627. $data_arr = array();
  1628. switch ($classkey) {
  1629. case 'assoc' :
  1630. while ($obj = mysql_fetch_assoc($result)) {
  1631. $data_arr [] = $obj;
  1632. }
  1633. break;
  1634. case 'num' :
  1635. while ($obj = mysql_fetch_row($result)) {
  1636. $data_arr [] = $obj;
  1637. }
  1638. break;
  1639. case 'both' :
  1640. case 'array' :
  1641. while ($obj = mysql_fetch_array($result)) {
  1642. $data_arr [] = $obj;
  1643. }
  1644. break;
  1645. case 'column' :
  1646. while ($obj = mysql_fetch_array($result)) {
  1647. if (isset($obj [$classname])) {
  1648. $data_arr [] = $obj [$classname];
  1649. } else {
  1650. $data_arr [] = null;
  1651. }
  1652. }
  1653. break;
  1654. default :
  1655. case 'class' :
  1656. if (isset($classkey_arr) && in_array('classtype', $classkey_arr)) {
  1657. while ($obj = mysql_fetch_assoc($result)) {
  1658. $obj_classname = $classname;
  1659. foreach ($obj as $key => $obj_classname) {
  1660. unset($obj [$key]);
  1661. break;
  1662. }
  1663. if (preg_match('/^[a-zA-Z_\x7f-\xff][a-zA-Z0-9_\x7f-\xff]*$/', $obj_classname) && class_exists($obj_classname)) {
  1664. $clone = new $obj_classname ( );
  1665. } elseif (class_exists($classname)) {
  1666. $clone = new $classname ( );
  1667. } else {
  1668. $clone = new $calledclass ( );
  1669. }
  1670. foreach ($obj as $key => $value) {
  1671. $clone->$key = $value;
  1672. }
  1673. $data_arr [] = $clone;
  1674. }
  1675. } else {
  1676. if (class_exists($classname)) {
  1677. $obj_classname = $classname;
  1678. } else {
  1679. $obj_classname = $calledclass;
  1680. }
  1681. while ($obj = mysql_fetch_object($result, $obj_classname)) {
  1682. $data_arr [] = $obj;
  1683. }
  1684. }
  1685. break;
  1686. case 'clone' :
  1687. if (is_object($classname)) {
  1688. $obj_classname = $classname;
  1689. } else {
  1690. $obj_classname = new $calledclass ( );
  1691. }
  1692. while ($obj = mysql_fetch_assoc($result)) {
  1693. $clone = clone $obj_classname;
  1694. foreach ($obj as $key => $value) {
  1695. $clone->$key = $value;
  1696. }
  1697. $data_arr [] = $clone;
  1698. }
  1699. break;
  1700. }
  1701. break;
  1702. }
  1703. // 整理
  1704. if ($class_arr === array(null) || $class_arr === array('')) {
  1705. return $data_arr;
  1706. }
  1707. $return = array();
  1708. foreach ($data_arr as $key => $data) {
  1709. $point1 = &$return;
  1710. foreach ($class_arr as $struct) {
  1711. $point2 = array();
  1712. if ($struct === null || $struct === '') {
  1713. $point1 [] = &$point2;
  1714. } else {
  1715. if (isset($data_all [$key] [$struct])) {
  1716. $point3 = $data_all [$key] [$struct];
  1717. } else {
  1718. $point3 = '';
  1719. }
  1720. if (isset($point1 [$point3])) {
  1721. $point2 = &$point1 [$point3];
  1722. } else {
  1723. $point1 [$point3] = &$point2;
  1724. }
  1725. }
  1726. unset($point1);
  1727. $point1 = &$point2;
  1728. unset($point2);
  1729. }
  1730. $point1 = $data;
  1731. }
  1732. return $return;
  1733. }
  1734. /**
  1735. * 静态插入函数(可继承)
  1736. *
  1737. * @link http://www.coremvc.cn/api/core/inserts.php
  1738. * @param mixed $table_sql
  1739. * @param mixed $column_set_param
  1740. * @param mixed $value_bool
  1741. * @param mixed $other
  1742. * @param string $class
  1743. * @return int
  1744. */
  1745. public static function inserts($table_sql = null, $column_set_param = null, $value_bool = null, $other = null, $class = null) {
  1746. // 【基础功能】静态插入数据
  1747. $dbh = self::connect(true, $args, array('inserts', $table_sql, $column_set_param, $value_bool, $other, $class));
  1748. // 参数
  1749. if (is_bool($value_bool)) {
  1750. $sql = $table_sql;
  1751. $param = $column_set_param;
  1752. } else {
  1753. if ($table_sql === null) {
  1754. if ($class === null) {
  1755. if (function_exists('get_called_class')) {
  1756. $class = get_called_class();
  1757. } else {
  1758. $class = __CLASS__;
  1759. }
  1760. }
  1761. if ($args ['prefix_search'] === '') {
  1762. $table = $class;
  1763. } else {
  1764. $table = $args ['prefix_search'] . $class;
  1765. }
  1766. } else {
  1767. $table = $table_sql;
  1768. }
  1769. $column_set = $column_set_param;
  1770. $value = $value_bool;
  1771. list ( $sql, $param ) = self::prepare('inserts', array($table, $column_set, $value, $other));
  1772. }
  1773. // 执行
  1774. switch ($args ['connect_provider']) {
  1775. // 【扩展功能】静态插入数据
  1776. default :
  1777. $callback = array($args ['connect_provider'], 'inserts');
  1778. if (is_callable($callback)) {
  1779. if ($args ['prefix_search'] !== '' && $args ['prefix_search'] !== $args ['prefix_replace']) {
  1780. $sql = str_replace($args ['prefix_search'], $args ['prefix_replace'], $sql);
  1781. }
  1782. return call_user_func($callback, $dbh, $args, __CLASS__, $sql, $param);
  1783. }
  1784. case '' :
  1785. case 'mysql' :
  1786. self::execute($sql, $param, $ref);
  1787. return $ref ['affected_rows'];
  1788. }
  1789. }
  1790. /**
  1791. * 静态修改函数(可继承)
  1792. *
  1793. * @link http://www.coremvc.cn/api/core/updates.php
  1794. * @param mixed $table_sql
  1795. * @param mixed $set_param
  1796. * @param mixed $where_bool
  1797. * @param mixed $other
  1798. * @param string $class
  1799. * @return int
  1800. */
  1801. public static function updates($table_sql = null, $set_param = null, $where_bool = null, $other = null, $class = null) {
  1802. // 【基础功能】静态修改数据
  1803. $dbh = self::connect(true, $args, array('updates', $table_sql, $set_param, $where_bool, $other, $class));
  1804. // 参数
  1805. if (is_bool($where_bool)) {
  1806. $sql = $table_sql;
  1807. $param = $set_param;
  1808. } else {
  1809. if ($table_sql === null) {
  1810. if ($class === null) {
  1811. if (function_exists('get_called_class')) {
  1812. $class = get_called_class();
  1813. } else {
  1814. $class = __CLASS__;
  1815. }
  1816. }
  1817. if ($args ['prefix_search'] === '') {
  1818. $table = $class;
  1819. } else {
  1820. $table = $args ['prefix_search'] . $class;
  1821. }
  1822. } else {
  1823. $table = $table_sql;
  1824. }
  1825. $set = $set_param;
  1826. $where = $where_bool;
  1827. list ( $sql, $param ) = self::prepare('updates', array($table, $set, $where, $other));
  1828. }
  1829. // 执行
  1830. switch ($args ['connect_provider']) {
  1831. // 【扩展功能】静态修改数据
  1832. default :
  1833. $callback = array($args ['connect_provider'], 'updates');
  1834. if (is_callable($callback)) {
  1835. if ($args ['prefix_search'] !== '' && $args ['prefix_search'] !== $args ['prefix_replace']) {
  1836. $sql = str_replace($args ['prefix_search'], $args ['prefix_replace'], $sql);
  1837. }
  1838. return call_user_func($callback, $dbh, $args, __CLASS__, $sql, $param);
  1839. }
  1840. case '' :
  1841. case 'mysql' :
  1842. self::execute($sql, $param, $ref);
  1843. return $ref ['affected_rows'];
  1844. }
  1845. }
  1846. /**
  1847. * 静态删除函数(可继承)
  1848. *
  1849. * @link http://www.coremvc.cn/api/core/deletes.php
  1850. * @param mixed $field_sql
  1851. * @param mixed $table_param
  1852. * @param mixed $where_bool
  1853. * @param mixed $other
  1854. * @param string $class
  1855. * @return int
  1856. */
  1857. public static function deletes($field_sql = null, $table_param = null, $where_bool = null, $other = null, $class = null) {
  1858. // 【基础功能】静态删除数据
  1859. $dbh = self::connect(true, $args, array('deletes', $field_sql, $table_param, $where_bool, $other, $class));
  1860. // 参数
  1861. if (is_bool($where_bool)) {
  1862. $sql = $field_sql;
  1863. $param = $table_param;
  1864. } else {
  1865. if ($table_param === null) {
  1866. if ($class === null) {
  1867. if (function_exists('get_called_class')) {
  1868. $class = get_called_class();
  1869. } else {
  1870. $class = __CLASS__;
  1871. }
  1872. }
  1873. if ($args ['prefix_search'] === '') {
  1874. $table = $class;
  1875. } else {
  1876. $table = $args ['prefix_search'] . $class;
  1877. }
  1878. } else {
  1879. $table = $table_param;
  1880. }
  1881. $field = $field_sql;
  1882. $where = $where_bool;
  1883. list ( $sql, $param ) = self::prepare('deletes', array($field, $table, $where, $other));
  1884. }
  1885. // 执行
  1886. switch ($args ['connect_provider']) {
  1887. // 【扩展功能】静态删除数据
  1888. default :
  1889. $callback = array($args ['connect_provider'], 'deletes');
  1890. if (is_callable($callback)) {
  1891. if ($args ['prefix_search'] !== '' && $args ['prefix_search'] !== $args ['prefix_replace']) {
  1892. $sql = str_replace($args ['prefix_search'], $args ['prefix_replace'], $sql);
  1893. }
  1894. return call_user_func($callback, $dbh, $args, __CLASS__, $sql, $param);
  1895. }
  1896. case '' :
  1897. case 'mysql' :
  1898. self::execute($sql, $param, $ref);
  1899. return $ref ['affected_rows'];
  1900. }
  1901. }
  1902. /**
  1903. * 静态更新函数(可继承)
  1904. *
  1905. * @link http://www.coremvc.cn/api/core/replaces.php
  1906. * @param mixed $table_sql
  1907. * @param mixed $column_set_param
  1908. * @param mixed $value_bool
  1909. * @param mixed $other
  1910. * @param string $class
  1911. * @return int
  1912. */
  1913. public static function replaces($table_sql = null, $column_set_param = null, $value_bool = null, $other = null, $class = null) {
  1914. // 【基础功能】静态更新数据
  1915. $dbh = self::connect(true, $args, array('replaces', $table_sql, $column_set_param, $value_bool, $other, $class));
  1916. // 参数
  1917. if (is_bool($value_bool)) {
  1918. $sql = $table_sql;
  1919. $param = $column_set_param;
  1920. } else {
  1921. if ($table_sql === null) {
  1922. if ($class === null) {
  1923. if (function_exists('get_called_class')) {
  1924. $class = get_called_class();
  1925. } else {
  1926. $class = __CLASS__;
  1927. }
  1928. }
  1929. if ($args ['prefix_search'] === '') {
  1930. $table = $class;
  1931. } else {
  1932. $table = $args ['prefix_search'] . $class;
  1933. }
  1934. } else {
  1935. $table = $table_sql;
  1936. }
  1937. $column_set = $column_set_param;
  1938. $value = $value_bool;
  1939. list ( $sql, $param ) = self::prepare('replaces', array($table, $column_set, $value, $other));
  1940. }
  1941. // 执行
  1942. switch ($args ['connect_provider']) {
  1943. // 【扩展功能】静态更新数据
  1944. default :
  1945. $callback = array($args ['connect_provider'], 'replaces');
  1946. if (is_callable($callback)) {
  1947. if ($args ['prefix_search'] !== '' && $args ['prefix_search'] !== $args ['prefix_replace']) {
  1948. $sql = str_replace($args ['prefix_search'], $args ['prefix_replace'], $sql);
  1949. }
  1950. return call_user_func($callback, $dbh, $args, __CLASS__, $sql, $param);
  1951. }
  1952. case '' :
  1953. case 'mysql' :
  1954. self::execute($sql, $param, $ref);
  1955. return $ref ['affected_rows'];
  1956. }
  1957. }
  1958. /**
  1959. * 实例构造函数(可继承)
  1960. *
  1961. * @link http://www.coremvc.cn/api/core/struct.php
  1962. * @param mixed $row
  1963. * @return mixed
  1964. */
  1965. public function struct($row = null) {
  1966. // 验证方法名
  1967. if (!isset($this) || !($this instanceof self)) {
  1968. trigger_error('Cannot find the correct object, try ' . __FUNCTION__ . 's method.', E_USER_ERROR);
  1969. return;
  1970. }
  1971. // 【基础功能】返回实例数组
  1972. if ($row === null || $row === '') {
  1973. return get_object_vars($this);
  1974. }
  1975. // 【基础功能】返回实例数据
  1976. if (is_int($row)) {
  1977. $i = 0;
  1978. foreach ($this as $value) {
  1979. if ($row === $i) {
  1980. return $value;
  1981. }
  1982. $i++;
  1983. }
  1984. return;
  1985. } elseif (is_string($row)) {
  1986. foreach ($this as $key => $value) {
  1987. if ($row === $key) {
  1988. return $value;
  1989. }
  1990. }
  1991. return;
  1992. }
  1993. // 【基础功能】载入实例数组
  1994. if (is_object($row)) {
  1995. foreach ($row as $key => $value) {
  1996. $this->$key = $value;
  1997. }
  1998. return get_object_vars($this);
  1999. } elseif (is_array($row)) {
  2000. foreach ($row as $key => $value) {
  2001. if (is_int($key)) {
  2002. $i = 0;
  2003. foreach ($this as $key2 => $value2) {
  2004. if ($key === $i) {
  2005. $this->$key2 = $value;
  2006. break;
  2007. }
  2008. $i++;
  2009. }
  2010. } elseif ($key !== '') {
  2011. $this->$key = $value;
  2012. }
  2013. }
  2014. return get_object_vars($this);
  2015. }
  2016. return;
  2017. }
  2018. /**
  2019. * 实例选择函数(可继承)
  2020. *
  2021. * @link http://www.coremvc.cn/api/core/select.php
  2022. * @param string $tablename
  2023. * @param mixed $primary_index
  2024. * @return bool
  2025. */
  2026. public function select($tablename = '', $primary_index = 0) {
  2027. // 验证方法名
  2028. if (!isset($this) || !($this instanceof self)) {
  2029. trigger_error('Cannot find the correct object, try ' . __FUNCTION__ . 's method.', E_USER_ERROR);
  2030. return;
  2031. }
  2032. // 【基础功能】选择实例数据
  2033. $dbh = self::connect(true, $args, array('select', $tablename, $primary_index));
  2034. // 表名
  2035. if (empty($tablename)) {
  2036. $tablename = $args ['prefix_search'] . get_class($this);
  2037. }
  2038. if ($args ['prefix_search'] !== '' && $args ['prefix_search'] !== $args ['prefix_replace']) {
  2039. $tablename = str_replace($args ['prefix_search'], $args ['prefix_replace'], $tablename);
  2040. }
  2041. // 字段
  2042. $fieldvars = get_object_vars($this);
  2043. $primary_name = null;
  2044. if (is_int($primary_index) && $primary_index >= 0 && $primary_index < count($fieldvars)) {
  2045. $field_index = 0;
  2046. foreach ($fieldvars as $primary_name => $primary_value) {
  2047. if ($primary_index === $field_index++) {
  2048. break;
  2049. }
  2050. }
  2051. } elseif (is_string($primary_index) && array_key_exists($primary_index, $fieldvars)) {
  2052. $primary_name = $primary_index;
  2053. $primary_value = $fieldvars [$primary_name];
  2054. }
  2055. // 执行
  2056. switch ($args ['connect_provider']) {
  2057. // 【扩展功能】选择实例数据
  2058. default :
  2059. $callback = array($args ['connect_provider'], 'select');
  2060. if (is_callable($callback)) {
  2061. $params = compact('primary_name', 'primary_value', 'fieldname', 'valuename', 'paramvars');
  2062. $result = call_user_func($callback, $dbh, $args, $this, $tablename, $primary_index, $params);
  2063. break;
  2064. }
  2065. case '' :
  2066. case 'mysql' :
  2067. if ($primary_name !== null) {
  2068. $sql = 'SELECT * FROM ' . $tablename . ' WHERE ' . $primary_name . '=? LIMIT 1';
  2069. $paramvars = array($primary_value);
  2070. } else {
  2071. $sql = 'SELECT * FROM ' . $tablename . ' LIMIT 1';
  2072. $paramvars = null;
  2073. }
  2074. $result = self::execute($sql, $paramvars);
  2075. if ($result === false) {
  2076. break;
  2077. ;
  2078. }
  2079. if (mysql_num_rows($result) == 0) {
  2080. mysql_free_result($result);
  2081. $result = false;
  2082. break;
  2083. }
  2084. $row = mysql_fetch_assoc($result);
  2085. mysql_free_result($result);
  2086. foreach ($row as $key => $value) {
  2087. $this->$key = $value;
  2088. }
  2089. $result = true;
  2090. break;
  2091. }
  2092. return $result;
  2093. }
  2094. /**
  2095. * 实例插入函数(可继承)
  2096. *
  2097. * @link http://www.coremvc.cn/api/core/insert.php
  2098. * @param string $tablename
  2099. * @param mixed $primary_index
  2100. * @return bool
  2101. */
  2102. public function insert($tablename = '', $primary_index = 0) {
  2103. // 验证方法名
  2104. if (!isset($this) || !($this instanceof self)) {
  2105. trigger_error('Cannot find the correct object, try ' . __FUNCTION__ . 's method.', E_USER_ERROR);
  2106. return;
  2107. }
  2108. // 【基础功能】插入实例数据
  2109. $dbh = self::connect(true, $args, array('insert', $tablename, $primary_index));
  2110. // 表名
  2111. if (empty($tablename)) {
  2112. $tablename = $args ['prefix_search'] . get_class($this);
  2113. }
  2114. if ($args ['prefix_search'] !== '' && $args ['prefix_search'] !== $args ['prefix_replace']) {
  2115. $tablename = str_replace($args ['prefix_search'], $args ['prefix_replace'], $tablename);
  2116. }
  2117. // 字段
  2118. $fieldvars = get_object_vars($this);
  2119. $primary_name = null;
  2120. if (is_int($primary_index) && $primary_index >= 0 && $primary_index < count($fieldvars)) {
  2121. $field_index = 0;
  2122. foreach ($fieldvars as $primary_name => $primary_value) {
  2123. if ($primary_index === $field_index++) {
  2124. unset($fieldvars [$primary_name]);
  2125. break;
  2126. }
  2127. }
  2128. } elseif (is_string($primary_index) && array_key_exists($primary_index, $fieldvars)) {
  2129. $primary_name = $primary_index;
  2130. $primary_value = $fieldvars [$primary_name];
  2131. unset($fieldvars [$primary_name]);
  2132. }
  2133. // 分析
  2134. $fieldname = implode(',', array_keys($fieldvars));
  2135. $valuename = implode(',', array_fill(0, count($fieldvars), '?'));
  2136. $paramvars = array_values($fieldvars);
  2137. // 执行
  2138. switch ($args ['connect_provider']) {
  2139. // 【扩展功能】插入实例数据
  2140. default :
  2141. $callback = array($args ['connect_provider'], 'insert');
  2142. if (is_callable($callback)) {
  2143. $params = compact('primary_name', 'primary_value', 'fieldname', 'valuename', 'paramvars');
  2144. $result = call_user_func($callback, $dbh, $args, $this, $tablename, $primary_index, $params);
  2145. break;
  2146. }
  2147. case '' :
  2148. case 'mysql' :
  2149. $sql = 'INSERT INTO ' . $tablename . ' (' . $fieldname . ') VALUES (' . $valuename . ')';
  2150. if ($primary_name !== null) {
  2151. $result = (bool) self::execute($sql, $paramvars, $ref);
  2152. if ($result) {
  2153. $this->$primary_name = $ref ['insert_id'];
  2154. }
  2155. } else {
  2156. $result = (bool) self::execute($sql, $paramvars);
  2157. }
  2158. break;
  2159. }
  2160. return $result;
  2161. }
  2162. /**
  2163. * 实例修改函数(可继承)
  2164. *
  2165. * @link http://www.coremvc.cn/api/core/update.php
  2166. * @param string $tablename
  2167. * @param mixed $primary_index
  2168. * @return bool
  2169. */
  2170. public function update($tablename = '', $primary_index = 0) {
  2171. // 验证方法名
  2172. if (!isset($this) || !($this instanceof self)) {
  2173. trigger_error('Cannot find the correct object, try ' . __FUNCTION__ . 's method.', E_USER_ERROR);
  2174. return;
  2175. }
  2176. // 【基础功能】修改实例数据
  2177. $dbh = self::connect(true, $args, array('update', $tablename, $primary_index));
  2178. // 表名
  2179. if (empty($tablename)) {
  2180. $tablename = $args ['prefix_search'] . get_class($this);
  2181. }
  2182. if ($args ['prefix_search'] !== '' && $args ['prefix_search'] !== $args ['prefix_replace']) {
  2183. $tablename = str_replace($args ['prefix_search'], $args ['prefix_replace'], $tablename);
  2184. }
  2185. // 字段
  2186. $fieldvars = get_object_vars($this);
  2187. $primary_name = null;
  2188. if (is_int($primary_index) && $primary_index >= 0 && $primary_index < count($fieldvars)) {
  2189. $field_index = 0;
  2190. foreach ($fieldvars as $primary_name => $primary_value) {
  2191. if ($primary_index === $field_index++) {
  2192. unset($fieldvars [$primary_name]);
  2193. break;
  2194. }
  2195. }
  2196. } elseif (is_string($primary_index) && array_key_exists($primary_index, $fieldvars)) {
  2197. $primary_name = $primary_index;
  2198. $primary_value = $fieldvars [$primary_name];
  2199. unset($fieldvars [$primary_name]);
  2200. }
  2201. // 分析
  2202. $fieldname = array_keys($fieldvars);
  2203. foreach ($fieldname as &$fieldname_value) {
  2204. $fieldname_value = $fieldname_value . '=?';
  2205. }
  2206. $valuename = implode(',', $fieldname);
  2207. $paramvars = array_values($fieldvars);
  2208. if ($primary_name !== null) {
  2209. array_push($paramvars, $primary_value);
  2210. }
  2211. // 执行
  2212. switch ($args ['connect_provider']) {
  2213. // 【扩展功能】修改实例数据
  2214. default :
  2215. $callback = array($args ['connect_provider'], 'update');
  2216. if (is_callable($callback)) {
  2217. $params = compact('primary_name', 'primary_value', 'fieldname', 'valuename', 'paramvars');
  2218. $result = call_user_func($callback, $dbh, $args, $this, $tablename, $primary_index, $params);
  2219. break;
  2220. }
  2221. case '' :
  2222. case 'mysql' :
  2223. if ($primary_name !== null) {
  2224. $sql = 'UPDATE ' . $tablename . ' SET ' . $valuename . ' WHERE ' . $primary_name . '=? LIMIT 1';
  2225. } else {
  2226. $sql = 'UPDATE ' . $tablename . ' SET ' . $valuename . ' LIMIT 1';
  2227. }
  2228. $result = (bool) self::execute($sql, $paramvars, $ref);
  2229. if ($result && $ref ['affected_rows'] == 0) {
  2230. return false;
  2231. }
  2232. break;
  2233. }
  2234. return $result;
  2235. }
  2236. /**
  2237. * 实例删除函数(可继承)
  2238. *
  2239. * @link http://www.coremvc.cn/api/core/delete.php
  2240. * @param string $tablename
  2241. * @param mixed $primary_index
  2242. * @return bool
  2243. */
  2244. public function delete($tablename = '', $primary_index = 0) {
  2245. // 验证方法名
  2246. if (!isset($this) || !($this instanceof self)) {
  2247. trigger_error('Cannot find the correct object, try ' . __FUNCTION__ . 's method.', E_USER_ERROR);
  2248. return;
  2249. }
  2250. // 【基础功能】删除实例数据
  2251. $dbh = self::connect(true, $args, array('delete', $tablename, $primary_index));
  2252. // 表名
  2253. if (empty($tablename)) {
  2254. $tablename = $args ['prefix_search'] . get_class($this);
  2255. }
  2256. if ($args ['prefix_search'] !== '' && $args ['prefix_search'] !== $args ['prefix_replace']) {
  2257. $tablename = str_replace($args ['prefix_search'], $args ['prefix_replace'], $tablename);
  2258. }
  2259. // 字段
  2260. $fieldvars = get_object_vars($this);
  2261. $primary_name = null;
  2262. if (is_int($primary_index) && $primary_index >= 0 && $primary_index < count($fieldvars)) {
  2263. $field_index = 0;
  2264. foreach ($fieldvars as $primary_name => $primary_value) {
  2265. if ($primary_index === $field_index++) {
  2266. break;
  2267. }
  2268. }
  2269. } elseif (is_string($primary_index) && array_key_exists($primary_index, $fieldvars)) {
  2270. $primary_name = $primary_index;
  2271. $primary_value = $fieldvars [$primary_name];
  2272. }
  2273. // 执行
  2274. switch ($args ['connect_provider']) {
  2275. // 【扩展功能】删除实例数据
  2276. default :
  2277. $callback = array($args ['connect_provider'], 'delete');
  2278. if (is_callable($callback)) {
  2279. $params = compact('primary_name', 'primary_value', 'fieldname', 'valuename', 'paramvars');
  2280. $result = call_user_func($callback, $dbh, $args, $this, $tablename, $primary_index, $params);
  2281. break;
  2282. }
  2283. case '' :
  2284. case 'mysql' :
  2285. if ($primary_name !== null) {
  2286. $sql = 'DELETE FROM ' . $tablename . ' WHERE ' . $primary_name . '=? LIMIT 1';
  2287. $paramvars = array($primary_value);
  2288. } else {
  2289. $sql = 'DELETE FROM ' . $tablename . ' LIMIT 1';
  2290. $paramvars = null;
  2291. }
  2292. $result = (bool) self::execute($sql, $paramvars, $ref);
  2293. if ($result && $ref['affected_rows'] == 0) {
  2294. $result = false;
  2295. }
  2296. break;
  2297. }
  2298. return $result;
  2299. }
  2300. /**
  2301. * 实例更新函数(可继承)
  2302. *
  2303. * @link http://www.coremvc.cn/api/core/replace.php
  2304. * @param string $tablename
  2305. * @param mixed $primary_index
  2306. * @return bool
  2307. */
  2308. public function replace($tablename = '', $primary_index = 0) {
  2309. // 验证方法名
  2310. if (!isset($this) || !($this instanceof self)) {
  2311. trigger_error('Cannot find the correct object, try ' . __FUNCTION__ . 's method.', E_USER_ERROR);
  2312. return;
  2313. }
  2314. // 【基础功能】更新实例数据
  2315. $dbh = self::connect(true, $args, array('replace', $tablename, $primary_index));
  2316. // 表名
  2317. if (empty($tablename)) {
  2318. $tablename = $args ['prefix_search'] . get_class($this);
  2319. }
  2320. if ($args ['prefix_search'] !== '' && $args ['prefix_search'] !== $args ['prefix_replace']) {
  2321. $tablename = str_replace($args ['prefix_search'], $args ['prefix_replace'], $tablename);
  2322. }
  2323. // 字段
  2324. $fieldvars = get_object_vars($this);
  2325. $primary_name = null;
  2326. if (is_int($primary_index) && $primary_index >= 0 && $primary_index < count($fieldvars)) {
  2327. $field_index = 0;
  2328. foreach ($fieldvars as $primary_name => $primary_value) {
  2329. if ($primary_index === $field_index++) {
  2330. break;
  2331. }
  2332. }
  2333. } elseif (is_string($primary_index) && array_key_exists($primary_index, $fieldvars)) {
  2334. $primary_name = $primary_index;
  2335. $primary_value = $fieldvars [$primary_name];
  2336. }
  2337. // 分析
  2338. $fieldname = implode(',', array_keys($fieldvars));
  2339. $valuename = implode(',', array_fill(0, count($fieldvars), '?'));
  2340. $paramvars = array_values($fieldvars);
  2341. // 执行
  2342. switch ($args ['connect_provider']) {
  2343. // 【扩展功能】更新实例数据
  2344. default :
  2345. $callback = array($args ['connect_provider'], 'replace');
  2346. if (is_callable($callback)) {
  2347. $params = compact('primary_name', 'primary_value', 'fieldname', 'valuename', 'paramvars');
  2348. $result = call_user_func($callback, $dbh, $args, $this, $tablename, $primary_index, $params);
  2349. break;
  2350. }
  2351. case '' :
  2352. case 'mysql' :
  2353. $sql = 'REPLACE INTO ' . $tablename . ' (' . $fieldname . ') VALUES (' . $valuename . ')';
  2354. if ($primary_name !== null) {
  2355. $result = (bool) self::execute($sql, $paramvars, $ref);
  2356. if ($result) {
  2357. $this->$primary_name = $ref ['insert_id'];
  2358. }
  2359. } else {
  2360. $result = (bool) self::execute($sql, $paramvars);
  2361. }
  2362. break;
  2363. }
  2364. return $result;
  2365. }
  2366. /**
  2367. * 载入配置文件
  2368. *
  2369. * @param string $filename
  2370. * @return array
  2371. */
  2372. private static function _init_file($filename) {
  2373. if (strtolower(strrchr($filename, '.')) === '.php') {
  2374. $filepath = self::_path_config($filename);
  2375. if (is_file($filepath)) {
  2376. $return = require $filepath;
  2377. }
  2378. }
  2379. if (!isset($return) || !is_array($return)) {
  2380. $return = array();
  2381. }
  2382. return $return;
  2383. }
  2384. /**
  2385. * 载入配置文件
  2386. *
  2387. * @param string $varname
  2388. * @return array
  2389. */
  2390. private static function _init_env($varname) {
  2391. //导入配置文件
  2392. static $static_htaccess;
  2393. if ($static_htaccess === null) {
  2394. $static_htaccess = array();
  2395. if (!isset($_SERVER[__CLASS__ . '_config']) && !isset($_SERVER[__CLASS__ . '_connect']) && !isset($_SERVER[__CLASS__ . '_view']) && is_file('.htaccess')) {
  2396. $content = file_get_contents('.htaccess');
  2397. if (preg_match_all('/^\s*SetEnv\s+(.+?)\s+(.*?)\s*$/im', $content, $matches)) {
  2398. $static_htaccess = array_combine($matches[1], $matches[2]);
  2399. parse_str(http_build_query($static_htaccess), $array);
  2400. $_SERVER = array_merge($_SERVER, $array);
  2401. }
  2402. }
  2403. }
  2404. //导入环境变量
  2405. static $static_config = array();
  2406. if (!isset($static_config [$varname])) {
  2407. $static_config [$varname] = array();
  2408. if (isset($_SERVER [__CLASS__ . '_' . $varname])) {
  2409. $config = &$static_config [$varname];
  2410. $config = $_SERVER [__CLASS__ . '_' . $varname];
  2411. if (is_string($config) && $config !== '') {
  2412. $config = self::_init_file($config);
  2413. }
  2414. if (!is_array($config)) {
  2415. $config = array();
  2416. }
  2417. }
  2418. }
  2419. return $static_config [$varname];
  2420. }
  2421. /**
  2422. * 类库载入功能
  2423. *
  2424. * @param array $array
  2425. */
  2426. private static function _init_extension($array) {
  2427. // 数组参数处理
  2428. $config = array(
  2429. 'extension_enable' => isset($array ['extension_enable']) ? $array ['extension_enable'] : '',
  2430. 'extension_path' => isset($array ['extension_path']) ? $array ['extension_path'] : '',
  2431. 'extension_prepend' => isset($array ['extension_prepend']) ? $array ['extension_prepend'] : '',
  2432. );
  2433. // 扩展类库功能
  2434. static $static_config = array(
  2435. 'extension_enable' => '',
  2436. 'extension_path' => '',
  2437. 'extension_prepend' => '',
  2438. );
  2439. if ($static_config !== $config) {
  2440. $extension_enable = $config ['extension_enable'];
  2441. $extension_prepend = $config['extension_prepend'];
  2442. // 类库功能启用
  2443. if ($extension_enable) {
  2444. $extension_path = rtrim(self::_path_extension(''), '/\\');
  2445. $include_path_array = explode(PATH_SEPARATOR, get_include_path());
  2446. if ($extension_prepend !== '') {
  2447. if (in_array($extension_path, $include_path_array)) {
  2448. $include_path_array = array_values(array_diff($include_path_array, array($extension_path)));
  2449. }
  2450. if ($extension_prepend) {
  2451. array_unshift($include_path_array, $extension_path);
  2452. } else {
  2453. array_push($include_path_array, $extension_path);
  2454. }
  2455. set_include_path(implode(PATH_SEPARATOR, $include_path_array));
  2456. } elseif (!in_array($extension_path, $include_path_array)) {
  2457. array_push($include_path_array, $extension_path);
  2458. set_include_path(implode(PATH_SEPARATOR, $include_path_array));
  2459. }
  2460. // 自动载入类库
  2461. if (is_string($extension_enable) && $extension_enable !== '1') {
  2462. $extension_array = explode(',', $extension_enable);
  2463. foreach ($extension_array as $extension) {
  2464. $extension_file = self::_path_extension(trim($extension) . '.php');
  2465. if (is_file($extension_file)) {
  2466. require_once $extension_file;
  2467. }
  2468. }
  2469. }
  2470. }
  2471. $static_config = $config;
  2472. }
  2473. }
  2474. /**
  2475. * 自动载入功能
  2476. *
  2477. * @param array $array
  2478. */
  2479. private static function _init_autoload($array) {
  2480. // 数组参数处理
  2481. $config = array(
  2482. 'autoload_enable' => isset($array ['autoload_enable']) ? $array ['autoload_enable'] : '',
  2483. 'autoload_path' => isset($array ['autoload_path']) ? $array ['autoload_path'] : '',
  2484. 'autoload_extensions' => isset($array ['autoload_extensions']) ? $array ['autoload_extensions'] : '',
  2485. 'autoload_prepend' => isset($array ['autoload_prepend']) ? $array ['autoload_prepend'] : '',
  2486. );
  2487. // 自动载入功能
  2488. static $static_config = array(
  2489. 'autoload_enable' => '',
  2490. 'autoload_path' => '',
  2491. 'autoload_extensions' => '',
  2492. 'autoload_prepend' => '',
  2493. );
  2494. static $static_last = array(
  2495. 'autoload_path' => '',
  2496. 'include_path' => '',
  2497. 'autoload_extensions' => '',
  2498. 'spl_autoload_extensions' => '',
  2499. 'autoload_enable' => '',
  2500. 'spl_autoload_functions' => '',
  2501. 'autoload_realname' => '',
  2502. );
  2503. if ($static_config !== $config) {
  2504. // 设置路径
  2505. if ($static_config ['autoload_path'] !== $config ['autoload_path'] || $static_config ['autoload_prepend'] !== $config ['autoload_prepend']) {
  2506. if (empty($static_last ['autoload_path'])) {
  2507. $static_last ['include_path'] = get_include_path();
  2508. }
  2509. if (empty($config ['autoload_path'])) {
  2510. set_include_path($static_last ['include_path']);
  2511. } else {
  2512. $autoload_realpath = self::path($config ['autoload_path']);
  2513. if (empty($config ['autoload_prepend'])) {
  2514. set_include_path($static_last ['include_path'] . PATH_SEPARATOR . $autoload_realpath);
  2515. } else {
  2516. set_include_path($autoload_realpath . PATH_SEPARATOR . $static_last ['include_path']);
  2517. }
  2518. }
  2519. $static_last ['autoload_path'] = $config ['autoload_path'];
  2520. }
  2521. // 设置扩展名
  2522. if ($static_config ['autoload_extensions'] !== $config ['autoload_extensions']) {
  2523. if (empty($static_last ['autoload_extensions'])) {
  2524. $static_last ['spl_autoload_extensions'] = spl_autoload_extensions();
  2525. }
  2526. if (empty($config ['autoload_extensions'])) {
  2527. spl_autoload_extensions($static_last ['spl_autoload_extensions']);
  2528. } else {
  2529. spl_autoload_extensions($config ['autoload_extensions']);
  2530. }
  2531. $static_last ['autoload_extensions'] = $config ['autoload_extensions'];
  2532. }
  2533. // 设置自动载入
  2534. if ($static_config ['autoload_enable'] !== $config ['autoload_enable'] || $static_config ['autoload_prepend'] !== $config ['autoload_prepend']) {
  2535. if (empty($static_last ['autoload_enable'])) {
  2536. $static_last ['spl_autoload_functions'] = spl_autoload_functions();
  2537. }
  2538. if (in_array($static_last ['autoload_realname'], (array) $static_last ['spl_autoload_functions'])) {
  2539. spl_autoload_unregister($static_last ['autoload_realname']);
  2540. }
  2541. if (!empty($config ['autoload_enable'])) {
  2542. if (is_callable($config ['autoload_enable'])) {
  2543. $static_last ['autoload_realname'] = $config ['autoload_enable'];
  2544. } else {
  2545. $static_last ['autoload_realname'] = 'spl_autoload';
  2546. }
  2547. if ($static_last ['spl_autoload_functions'] === array('__autoload')) {
  2548. spl_autoload_register('__autoload');
  2549. }
  2550. if (version_compare(PHP_VERSION, '5.3.0', '>=')) {
  2551. if (empty($config ['autoload_prepend'])) {
  2552. spl_autoload_register($static_last ['autoload_realname'], true, false);
  2553. } else {
  2554. spl_autoload_register($static_last ['autoload_realname'], true, true);
  2555. }
  2556. } else {
  2557. spl_autoload_register($static_last ['autoload_realname']);
  2558. }
  2559. }
  2560. $static_last ['autoload_enable'] = $config ['autoload_enable'];
  2561. }
  2562. $static_config = $config;
  2563. }
  2564. }
  2565. /**
  2566. * 第一次自动载入
  2567. *
  2568. * @param array $array
  2569. */
  2570. private static function _stub_autoload($array) {
  2571. static $static_config;
  2572. if ($static_config === null || $array !== array()) {
  2573. $static_config = $array;
  2574. self::init($array);
  2575. }
  2576. }
  2577. /**
  2578. * 入口函数(可继承)
  2579. *
  2580. * @param array $array
  2581. */
  2582. private static function _main_hide($array) {
  2583. $hide_info = isset($array ['hide_info']) ? $array ['hide_info'] : '';
  2584. $hide_info_cli = isset($array ['hide_info_cli']) ? $array ['hide_info_cli'] : $hide_info;
  2585. $hide_info_web = isset($array ['hide_info_web']) ? $array ['hide_info_web'] : $hide_info;
  2586. if (PHP_SAPI == 'cli') {
  2587. if (empty($hide_info_cli)) {
  2588. echo ('Could not open input file: ' . basename($_SERVER ['SCRIPT_FILENAME']) . PHP_EOL);
  2589. } elseif (is_callable($hide_info_cli)) {
  2590. call_user_func($hide_info_cli);
  2591. echo PHP_EOL;
  2592. } else {
  2593. echo $hide_info_cli . PHP_EOL;
  2594. }
  2595. } else {
  2596. if (empty($hide_info_web)) {
  2597. header('HTTP/1.0 404 Not Found');
  2598. } elseif (is_callable($hide_info_web)) {
  2599. call_user_func($hide_info_web);
  2600. } elseif (filter_var($hide_info_web, FILTER_VALIDATE_URL)) {
  2601. header('Location: ' . $hide_info_web);
  2602. } else {
  2603. header("Content-type:text/html;charset=UTF-8");
  2604. echo $hide_info_web;
  2605. }
  2606. }
  2607. }
  2608. /**
  2609. * 框架控制函数
  2610. *
  2611. * @param array $array
  2612. * @param array $return_array
  2613. * @return mixed
  2614. */
  2615. private static function _main_framework($array, $return_array) {
  2616. // 1. 设置默认值、替换内置宏
  2617. list ($classname_static, $debug_backtrace_file) = self::_main_framework_first();
  2618. if (empty($array ['framework_require'])) {
  2619. $require = '';
  2620. } else {
  2621. $require = $array ['framework_require'];
  2622. if (strpos($require, '(self)') !== false) {
  2623. $require = str_replace('(self)', __CLASS__, $require);
  2624. }
  2625. if (strpos($require, '(static)') !== false) {
  2626. $require = str_replace('(static)', $classname_static, $require);
  2627. }
  2628. }
  2629. if (empty($array ['framework_module'])) {
  2630. $module = $classname_static . '!' . __CLASS__; //默认值:(static)!(self)
  2631. } else {
  2632. $module = $array ['framework_module'];
  2633. if (strpos($module, '(self)') !== false) {
  2634. $module = str_replace('(self)', __CLASS__, $module);
  2635. }
  2636. if (strpos($module, '(static)') !== false) {
  2637. $module = str_replace('(static)', $classname_static, $module);
  2638. }
  2639. }
  2640. if (empty($array ['framework_action'])) {
  2641. $action = '[get:1]|index'; //默认值:[get:1]|index
  2642. } else {
  2643. $action = $array ['framework_action'];
  2644. }
  2645. $action_multi = is_array($action);
  2646. if ($action_multi) {
  2647. $action_array = &$action;
  2648. $action_string = implode(' ', $action);
  2649. } else {
  2650. $action_array = array(&$action);
  2651. $action_string = $action;
  2652. }
  2653. foreach ($action_array as &$action_value) {
  2654. if (strpos($action_value, '(self)') !== false) {
  2655. $action_value = str_replace('(self)', __CLASS__, $action_value);
  2656. }
  2657. if (strpos($action_value, '(static)') !== false) {
  2658. $action_value = str_replace('(static)', $classname_static, $action_value);
  2659. }
  2660. }
  2661. if (empty($array ['framework_parameter'])) {
  2662. $parameter = '';
  2663. } else {
  2664. $parameter = $array ['framework_parameter'];
  2665. }
  2666. $parameter_multi = is_array($parameter);
  2667. if ($parameter_multi) {
  2668. $parameter_array = &$parameter;
  2669. $parameter_string = implode(' ', $parameter);
  2670. } else {
  2671. $parameter_array = array(&$parameter);
  2672. $parameter_string = $parameter;
  2673. }
  2674. foreach ($parameter_array as &$parameter_value) {
  2675. if (strpos($parameter_value, '(self)') !== false) {
  2676. $parameter_value = str_replace('(self)', __CLASS__, $parameter_value);
  2677. }
  2678. if (strpos($parameter_value, '(static)') !== false) {
  2679. $parameter_value = str_replace('(static)', $classname_static, $parameter_value);
  2680. }
  2681. }
  2682. // 2. 生成替换数组
  2683. $value_array = array();
  2684. $string = $require . ' ' . $module . ' ' . $action_string . ' ' . $parameter_string;
  2685. if (stripos($string, '[get:') !== false) {
  2686. $get_array = array_values($_GET) + $_GET;
  2687. array_unshift($get_array, null);
  2688. $value_array ['get'] = $get_array;
  2689. }
  2690. if (stripos($string, '[post:') !== false) {
  2691. $post_array = array_values($_POST) + $_POST;
  2692. array_unshift($post_array, null);
  2693. $value_array ['post'] = $post_array;
  2694. }
  2695. if (stripos($string, '[query:') !== false) {
  2696. $query_array = array();
  2697. if (isset($_SERVER ['QUERY_STRING'])) {
  2698. $query_string = $_SERVER['QUERY_STRING'];
  2699. $query_array = explode('&', $query_string);
  2700. array_unshift($query_array, $query_string);
  2701. }
  2702. $value_array ['query'] = $query_array;
  2703. }
  2704. if (stripos($string, '[path:') !== false) {
  2705. $path_array = array();
  2706. if (isset($_SERVER ['PATH_INFO'])) {
  2707. $path_info = trim($_SERVER ['PATH_INFO'], '/');
  2708. $path_array [] = $path_info;
  2709. $tok = strtok($path_info, '/');
  2710. while ($tok !== false) {
  2711. $path_array [] = $tok;
  2712. $tok = strtok('/');
  2713. }
  2714. }
  2715. $path_array ['path'] = $path_array;
  2716. $value_array ['path'] = $path_array;
  2717. }
  2718. if (stripos($string, '[file:') !== false) {
  2719. $file_array = array();
  2720. if ($debug_backtrace_file === null) {
  2721. list (, $row) = debug_backtrace();
  2722. $debug_backtrace_file = $row ['file'];
  2723. }
  2724. strtok($debug_backtrace_file, '/\\');
  2725. while (($tok = strtok('/\\')) !== false) {
  2726. array_unshift($file_array, $tok);
  2727. }
  2728. $file_array [0] = strtok($file_array [0], '.');
  2729. array_unshift($file_array, strtok('.'));
  2730. $value_array ['file'] = $file_array;
  2731. }
  2732. // 3. 生成返回数组
  2733. $return4_array = array_values(array_intersect($return_array, array('require', 'module', 'action', 'parameter')));
  2734. if (empty($return4_array)) {
  2735. $return4_result = array();
  2736. $return4_final = '';
  2737. } else {
  2738. $return4_result = array_flip($return4_array);
  2739. if (isset($return4_result ['require'])) {
  2740. $return4_result ['require'] = false;
  2741. $return4_final = 'require';
  2742. }
  2743. if (isset($return4_result ['module'])) {
  2744. $return4_result ['module'] = false;
  2745. $return4_final = 'module';
  2746. }
  2747. if (isset($return4_result ['action'])) {
  2748. $return4_result ['action'] = false;
  2749. $return4_final = 'action';
  2750. }
  2751. if (isset($return4_result ['parameter'])) {
  2752. $return4_result ['parameter'] = false;
  2753. $return4_final = 'parameter';
  2754. }
  2755. }
  2756. // 4. 处理引用部份
  2757. $require_now = '';
  2758. if ($require) {
  2759. $result_array = self::_main_framework_resolve($require, $value_array, 'require');
  2760. foreach ($result_array as $value) {
  2761. $value_file = self::_path_file($value);
  2762. if (is_file($value_file)) {
  2763. $require_now = $value;
  2764. $require_name = $value_file;
  2765. break;
  2766. }
  2767. }
  2768. if ($require_now === '') {
  2769. if ($return4_final === '') {
  2770. if (!in_array('manual', $return_array)) {
  2771. self::_main_hide($array);
  2772. }
  2773. return false;
  2774. } elseif (count($return4_array) === 1) {
  2775. return false;
  2776. } else {
  2777. return array_values($return4_result);
  2778. }
  2779. }
  2780. require_once $require_name;
  2781. }
  2782. if (isset($return4_result ['require'])) {
  2783. $return4_result ['require'] = $require_now;
  2784. }
  2785. if ($return4_array === array('require')) {
  2786. return $require_now;
  2787. } elseif ($return4_final === 'require') {
  2788. return array_values($return4_result);
  2789. }
  2790. // 5. 处理模块部份
  2791. $module_now = '';
  2792. $result_array = self::_main_framework_resolve($module, $value_array, 'module');
  2793. foreach ($result_array as $value) {
  2794. if (preg_match('/(^|\\\\)[0-9]/', $value) === 1) {
  2795. continue;
  2796. }
  2797. try {
  2798. if (!class_exists($value)) {
  2799. continue;
  2800. }
  2801. } catch (Exception $e) {
  2802. continue;
  2803. }
  2804. $class = new ReflectionClass($value);
  2805. if ($class->isInternal() || $class->isAbstract() || $class->isInterface()) {
  2806. continue;
  2807. }
  2808. $module_now = $value;
  2809. break;
  2810. }
  2811. if ($module_now === '') {
  2812. if ($return4_final === '') {
  2813. if (!in_array('manual', $return_array)) {
  2814. self::_main_hide($array);
  2815. }
  2816. return false;
  2817. } elseif (count($return4_array) === 1) {
  2818. return false;
  2819. } else {
  2820. return array_values($return4_result);
  2821. }
  2822. } else {
  2823. if (isset($return4_result ['module'])) {
  2824. $return4_result ['module'] = $module_now;
  2825. }
  2826. if ($return4_array === array('module')) {
  2827. return $module_now;
  2828. } elseif ($return4_final === 'module') {
  2829. return array_values($return4_result);
  2830. }
  2831. }
  2832. // 6. 处理动作部份
  2833. if ($action_multi) {
  2834. $action_now = array();
  2835. } else {
  2836. $action_now = false;
  2837. }
  2838. foreach ($action_array as $action_key => &$action_value) {
  2839. $action_now2 = false;
  2840. $action_extra = strncmp($action_value, '*|', 2) === 0;
  2841. if ($action_extra) {
  2842. $action_value2 = substr($action_value, 2);
  2843. $action_now2 = '';
  2844. } else {
  2845. $action_value2 = $action_value;
  2846. }
  2847. $result_array = self::_main_framework_resolve($action_value2, $value_array, 'action', $module_now);
  2848. foreach ($result_array as $value) {
  2849. list ($module_new, $action_new) = $value;
  2850. if ($module_new === '(function)') {
  2851. if (!function_exists($action_new)) {
  2852. continue;
  2853. }
  2854. $module_now2 = '';
  2855. $action_now2 = $action_new;
  2856. break;
  2857. } else {
  2858. if ($module_new !== $module_now) {
  2859. if (preg_match('/(^|\\\\)[0-9]/', $module_new) === 1) {
  2860. continue;
  2861. }
  2862. try {
  2863. if (!class_exists($module_new)) {
  2864. continue;
  2865. }
  2866. } catch (Exception $e) {
  2867. continue;
  2868. }
  2869. $class = new ReflectionClass($module_new);
  2870. if ($class->isAbstract() || $class->isInterface()) {
  2871. continue;
  2872. }
  2873. if (!$action_extra && $class->isInternal()) {
  2874. continue;
  2875. }
  2876. }
  2877. if (!method_exists($module_new, $action_new)) {
  2878. continue;
  2879. }
  2880. $method = new ReflectionMethod($module_new, $action_new);
  2881. if (!$method->isPublic() || $method->isConstructor() || $method->isDestructor()) {
  2882. continue;
  2883. }
  2884. if (!$action_extra && in_array('static', $return_array) && !in_array('object', $return_array)) {
  2885. if (!$method->isStatic()) {
  2886. continue;
  2887. }
  2888. } elseif (!$action_extra && in_array('object', $return_array) && !in_array('static', $return_array)) {
  2889. if ($method->isStatic()) {
  2890. continue;
  2891. }
  2892. }
  2893. if (!$action_extra && in_array('final', $return_array)) {
  2894. if (!$method->isFinal()) {
  2895. continue;
  2896. }
  2897. }
  2898. $module_now2 = $method->isStatic() ? $module_new : new $module_new;
  2899. $action_now2 = $action_new;
  2900. break;
  2901. }
  2902. }
  2903. if ($action_now2 === false) {
  2904. if (!$action_extra) {
  2905. if ($action_multi) {
  2906. $action_now = array();
  2907. } else {
  2908. $action_now = false;
  2909. }
  2910. break;
  2911. }
  2912. } elseif ($action_now2 === '') {
  2913. if ($action_multi) {
  2914. $action_now [$action_key] = '';
  2915. } else {
  2916. $action_now = '';
  2917. }
  2918. } else {
  2919. if ($action_multi) {
  2920. if ($module_now2 === '') {
  2921. $action_now [$action_key] = $action_now2;
  2922. } else {
  2923. $action_now [$action_key] = array($module_now2, $action_now2);
  2924. }
  2925. } else {
  2926. $module_now = $module_now2;
  2927. $action_now = $action_now2;
  2928. if (isset($return4_result ['module'])) {
  2929. $return4_result ['module'] = $module_now;
  2930. }
  2931. }
  2932. }
  2933. }
  2934. if ($action_now === false || $action === array()) {
  2935. if ($return4_final === '') {
  2936. if (!in_array('manual', $return_array)) {
  2937. self::_main_hide($array);
  2938. }
  2939. return false;
  2940. } elseif (count($return4_array) === 1) {
  2941. return false;
  2942. } else {
  2943. return array_values($return4_result);
  2944. }
  2945. } else {
  2946. if (isset($return4_result ['action'])) {
  2947. $return4_result ['action'] = $action_now;
  2948. }
  2949. if ($return4_array === array('action')) {
  2950. return $action_now;
  2951. } elseif ($return4_final === 'action') {
  2952. return array_values($return4_result);
  2953. }
  2954. }
  2955. // 7. 处理参数部份
  2956. $parameter_now = array();
  2957. if ($action_multi) {
  2958. foreach ($action_now as $action_key => &$action_value) {
  2959. $parameter_now [$action_key] = array();
  2960. if ($parameter && is_array($parameter) && isset($parameter [$action_key]) && $action_value !== '') {
  2961. if (!is_array($action_value)) {
  2962. $module_now3 = '';
  2963. $action_now3 = $action_value;
  2964. } elseif (is_object($action_value [0])) {
  2965. $module_now3 = get_class($action_value [0]);
  2966. $action_now3 = $action_value [1];
  2967. } else {
  2968. $module_now3 = $action_value [0];
  2969. $action_now3 = $action_value [1];
  2970. }
  2971. $result_array = self::_main_framework_resolve($parameter [$action_key], $value_array, 'parameter', array($module_now3, $action_now3));
  2972. foreach ($result_array as $value) {
  2973. $parameter_now [$action_key] = array_slice($value, 2);
  2974. break;
  2975. }
  2976. }
  2977. }
  2978. } else {
  2979. if ($parameter && $action_now !== '') {
  2980. $module_now3 = is_object($module_now) ? get_class($module_now) : $module_now;
  2981. $action_now3 = $action_now;
  2982. $result_array = self::_main_framework_resolve($parameter, $value_array, 'parameter', array($module_now3, $action_now3));
  2983. foreach ($result_array as $value) {
  2984. $parameter_now = array_slice($value, 2);
  2985. break;
  2986. }
  2987. }
  2988. }
  2989. if (isset($return4_result ['parameter'])) {
  2990. $return4_result ['parameter'] = $parameter_now;
  2991. }
  2992. if ($return4_array === array('parameter')) {
  2993. return $parameter_now;
  2994. } elseif ($return4_final === 'parameter') {
  2995. return array_values($return4_result);
  2996. }
  2997. // 8. 执行
  2998. if ($action_multi) {
  2999. $return = array();
  3000. foreach ($action_now as $action_key => &$action_value) {
  3001. if ($action_value === '') {
  3002. $return [$action_key] = null;
  3003. } elseif ($action_value [0] === '') {
  3004. $return [$action_key] = call_user_func_array($action_value [1], $parameter_now [$action_key]);
  3005. } else {
  3006. $return [$action_key] = call_user_func_array($action_value, $parameter_now [$action_key]);
  3007. }
  3008. }
  3009. } else {
  3010. if ($action_now === '') {
  3011. $return = null;
  3012. } elseif ($module_now === '') {
  3013. $return = call_user_func_array($action_now, $parameter_now);
  3014. } else {
  3015. $return = call_user_func_array(array($module_now, $action_now), $parameter_now);
  3016. }
  3017. }
  3018. if (in_array('return', $return_array)) {
  3019. return $return;
  3020. } else {
  3021. return true;
  3022. }
  3023. }
  3024. /**
  3025. * 框架第一现场
  3026. *
  3027. * @param bool $bool
  3028. * @return array
  3029. */
  3030. private static function _main_framework_first($bool = null) {
  3031. static $class = null;
  3032. static $file = null;
  3033. if ($class === null) {
  3034. if (function_exists('get_called_class')) {
  3035. $class = get_called_class();
  3036. } else {
  3037. $class = '[file:1]';
  3038. }
  3039. }
  3040. if ($bool && $file === null) {
  3041. list (, $row) = debug_backtrace();
  3042. $file = $row ['file'];
  3043. }
  3044. return array($class, $file);
  3045. }
  3046. /**
  3047. * 框架规则解析
  3048. *
  3049. * @param string $string
  3050. * @param array $value_array
  3051. * @param string $flag
  3052. * @param mixed $prefix
  3053. * @return array
  3054. */
  3055. private static function _main_framework_resolve($string, $value_array, $flag, $prefix = null) {
  3056. $result_array = array();
  3057. $length = strlen($string);
  3058. $last_pos = 0;
  3059. $last_bracket = '|';
  3060. $left_pos1 = 0;
  3061. $left_pos2 = 0;
  3062. $left_pos3 = 0;
  3063. while (true) {
  3064. // 寻找“或且非”截断的字符串
  3065. if ($last_pos >= $length) {
  3066. break;
  3067. }
  3068. $left_pos1 === false or $left_pos1 = strpos($string, '|', $last_pos);
  3069. $left_pos2 === false or $left_pos2 = strpos($string, '&', $last_pos);
  3070. $left_pos3 === false or $left_pos3 = strpos($string, '!', $last_pos);
  3071. if ($left_pos1 === false && $left_pos2 === false && $left_pos3 === false) {
  3072. $str = substr($string, $last_pos);
  3073. $left_bracket = '';
  3074. $last_pos = $length + 1;
  3075. } else {
  3076. $left_pos = false;
  3077. if ($left_pos === false || $left_pos1 !== false && $left_pos1 < $left_pos) {
  3078. $left_pos = $left_pos1;
  3079. $left_bracket = '|';
  3080. }
  3081. if ($left_pos === false || $left_pos2 !== false && $left_pos2 < $left_pos) {
  3082. $left_pos = $left_pos2;
  3083. $left_bracket = '&';
  3084. }
  3085. if ($left_pos === false || $left_pos3 !== false && $left_pos3 < $left_pos) {
  3086. $left_pos = $left_pos3;
  3087. $left_bracket = '!';
  3088. }
  3089. $str = substr($string, $last_pos, $left_pos - $last_pos);
  3090. if ($left_bracket === '') {
  3091. break;
  3092. }
  3093. $last_pos = $left_pos + 1;
  3094. }
  3095. $deal_bracket = $last_bracket;
  3096. $last_bracket = $left_bracket;
  3097. if ($str === '') {
  3098. continue;
  3099. }
  3100. if ($flag === 'parameter' && $deal_bracket === '|') {
  3101. $arr = explode(',', $str);
  3102. $str = $prefix;
  3103. foreach ($arr as $value) {
  3104. if (strpos($value, '(comma)') !== false) {
  3105. $value = str_replace('(comma)', ',', $value);
  3106. }
  3107. if (strpos($value, '(module)') !== false) {
  3108. $value = str_replace('(module)', $prefix[0], $value);
  3109. }
  3110. if (strpos($value, '(action)') !== false) {
  3111. $value = str_replace('(action)', $prefix[1], $value);
  3112. }
  3113. if (strpos($value, '(open_paren)') !== false || strpos($value, '(close_paren)') !== false) {
  3114. $value = str_replace(array('(open_paren)', '(close_paren)'), array('(', ')'), $value);
  3115. }
  3116. $str [] = self::_main_framework_replace($value, $value_array, false);
  3117. }
  3118. } else {
  3119. $str = self::_main_framework_replace($str, $value_array, true);
  3120. if ($str === false || $str === '') {
  3121. continue;
  3122. }
  3123. }
  3124. // 处理“或且非”截断的字符串
  3125. switch ($deal_bracket) {
  3126. case '|':
  3127. // “或”的处理
  3128. if ($flag === 'action') {
  3129. if (strpos($str, '::') === false) {
  3130. $result_array [] = array($prefix, $str);
  3131. } else {
  3132. list ($str1, $str2) = explode('::', $str);
  3133. if ($str1 === '' || $str2 === '') {
  3134. continue 2;
  3135. }
  3136. $result_array [] = array($str1, $str2);
  3137. }
  3138. } else {
  3139. $result_array [] = $str;
  3140. }
  3141. break;
  3142. case '&':
  3143. // “且”的处理
  3144. if ($flag === 'action' || $flag === 'parameter') {
  3145. if (strpos($str, '::') === false) {
  3146. $str1 = '';
  3147. $str2 = $str;
  3148. } else {
  3149. list ($str1, $str2) = explode('::', $str);
  3150. }
  3151. $bool_reg1 = strpos($str1, '*') !== false;
  3152. if ($bool_reg1) {
  3153. $str1 = '/' . str_replace('\\*', '.*?', preg_quote($str1, '/')) . '/';
  3154. }
  3155. $bool_reg2 = strpos($str2, '*') !== false;
  3156. if ($bool_reg2) {
  3157. $str2 = '/' . str_replace('\\*', '.*?', preg_quote($str2, '/')) . '/';
  3158. }
  3159. $right_array = array();
  3160. foreach ($result_array as $value) {
  3161. if (($str1 === '' || $bool_reg1 && preg_match($str1, $value[0]) === 1 || $str1 === $value[0]) &&
  3162. ($str2 === '' || $bool_reg2 && preg_match($str2, $value[1]) === 1 || $str2 === $value[1])) {
  3163. $right_array [] = $value;
  3164. }
  3165. }
  3166. $result_array = $right_array;
  3167. } else {
  3168. $bool_reg = strpos($str, '*') !== false;
  3169. if ($bool_reg) {
  3170. $str = '/' . str_replace('\\*', '.*?', preg_quote($str, '/')) . '/';
  3171. }
  3172. $right_array = array();
  3173. foreach ($result_array as $value) {
  3174. if ($bool_reg && preg_match($str, $value) === 1 || !$bool_reg && $str === $value) {
  3175. $right_array [] = $value;
  3176. }
  3177. }
  3178. $result_array = $right_array;
  3179. }
  3180. break;
  3181. case '!':
  3182. // “非”的处理
  3183. if ($flag === 'action' || $flag === 'parameter') {
  3184. if (strpos($str, '::') === false) {
  3185. $str1 = '';
  3186. $str2 = $str;
  3187. } else {
  3188. list ($str1, $str2) = explode('::', $str);
  3189. }
  3190. $bool_reg1 = strpos($str1, '*') !== false;
  3191. if ($bool_reg1) {
  3192. $str1 = '/' . str_replace('\\*', '.*?', preg_quote($str1, '/')) . '/';
  3193. }
  3194. $bool_reg2 = strpos($str2, '*') !== false;
  3195. if ($bool_reg2) {
  3196. $str2 = '/' . str_replace('\\*', '.*?', preg_quote($str2, '/')) . '/';
  3197. }
  3198. $right_array = array();
  3199. foreach ($result_array as $value) {
  3200. if ($str1 !== '' && ($bool_reg1 && preg_match($str1, $value[0]) !== 1 || !$bool_reg1 && $str1 !== $value[0]) ||
  3201. $str2 !== '' && ($bool_reg2 && preg_match($str2, $value[1]) !== 1 || !$bool_reg2 && $str2 !== $value[1])) {
  3202. $right_array [] = $value;
  3203. }
  3204. }
  3205. $result_array = $right_array;
  3206. } else {
  3207. $bool_reg = strpos($str, '*') !== false;
  3208. if ($bool_reg) {
  3209. $str = '/' . str_replace('\\*', '.*?', preg_quote($str, '/')) . '/';
  3210. }
  3211. $right_array = array();
  3212. foreach ($result_array as $value) {
  3213. if ($bool_reg && preg_match($str, $value) !== 1 || !$bool_reg && $str !== $value) {
  3214. $right_array [] = $value;
  3215. }
  3216. }
  3217. $result_array = $right_array;
  3218. }
  3219. break;
  3220. }
  3221. }
  3222. return $result_array;
  3223. }
  3224. /**
  3225. * 框架字串替换
  3226. *
  3227. * @param string $string
  3228. * @param array $value_array
  3229. * @param bool $strict
  3230. * @return array
  3231. */
  3232. private static function _main_framework_replace($string, $value_array, $strict) {
  3233. $result = '';
  3234. $length = strlen($string);
  3235. $last_pos = 0;
  3236. $left_pos1 = 0;
  3237. $left_pos2 = 0;
  3238. while (true) {
  3239. // 寻找需要替换字串
  3240. if ($last_pos >= $length) {
  3241. break;
  3242. }
  3243. $left_pos1 === false or $left_pos1 = strpos($string, '[', $last_pos);
  3244. $left_pos2 === false or $left_pos2 = strpos($string, '{', $last_pos);
  3245. if ($left_pos1 === false && $left_pos2 === false) {
  3246. $result .= substr($string, $last_pos);
  3247. break;
  3248. } elseif ($left_pos1 === false) {
  3249. $left_pos = $left_pos2;
  3250. $right_bracket = '}';
  3251. } elseif ($left_pos2 === false) {
  3252. $left_pos = $left_pos1;
  3253. $right_bracket = ']';
  3254. } elseif ($left_pos1 > $left_pos2) {
  3255. $left_pos = $left_pos2;
  3256. $right_bracket = '}';
  3257. } else {
  3258. $left_pos = $left_pos1;
  3259. $right_bracket = ']';
  3260. }
  3261. $result .= substr($string, $last_pos, $left_pos - $last_pos);
  3262. $last_pos = $left_pos + 1;
  3263. $right_pos = strpos($string, $right_bracket, $last_pos);
  3264. if ($right_pos === false) {
  3265. return false;
  3266. }
  3267. $keyword = substr($string, $last_pos, $right_pos - $last_pos);
  3268. if ($keyword === '') {
  3269. continue;
  3270. }
  3271. $last_pos = $right_pos + 1;
  3272. // 替换成POST值
  3273. if ($right_bracket === '}') {
  3274. if (isset($_POST [$keyword])) {
  3275. $valueword = $_POST [$keyword];
  3276. } else {
  3277. if ($strict) {
  3278. return false;
  3279. }
  3280. continue;
  3281. }
  3282. // 替换成GET值
  3283. } elseif (strpos($keyword, ':') === false) {
  3284. if (isset($_GET [$keyword])) {
  3285. $valueword = $_GET [$keyword];
  3286. } else {
  3287. if ($strict) {
  3288. return false;
  3289. }
  3290. continue;
  3291. }
  3292. // 替换成其他定义值
  3293. } else {
  3294. list ($key, $sub) = explode(':', $keyword);
  3295. if ($key === '' || $sub === '') {
  3296. continue;
  3297. }
  3298. $key_lower = strtolower($key);
  3299. $key_upper = strtoupper($key);
  3300. $key_ucfirst = ucfirst($key_lower);
  3301. $key_lcfirst = $key_upper;
  3302. if (strlen($key_lcfirst) > 0) {
  3303. $key_lcfirst[0] = strtolower($key_lcfirst[0]);
  3304. }
  3305. switch ($key_lower) {
  3306. case 'get':
  3307. case 'post':
  3308. case 'query':
  3309. case 'path':
  3310. case 'file':
  3311. $valueword = isset($value_array [$key_lower] [$sub]) ? $value_array [$key_lower] [$sub] : '';
  3312. break;
  3313. default:
  3314. $valueword = '';
  3315. break;
  3316. }
  3317. switch ($key) {
  3318. case $key_lower:
  3319. break;
  3320. case $key_upper:
  3321. $valueword = strtoupper($valueword);
  3322. break;
  3323. case $key_ucfirst:
  3324. $valueword = ucfirst(strtolower($valueword));
  3325. break;
  3326. case $key_lcfirst:
  3327. $valueword = strtoupper($valueword);
  3328. if (strlen($valueword) > 0) {
  3329. $valueword[0] = strtolower($valueword[0]);
  3330. }
  3331. break;
  3332. default:
  3333. $valueword = strtolower($valueword);
  3334. break;
  3335. }
  3336. }
  3337. // 验证命名规则
  3338. if ($strict && preg_match('/^[a-zA-Z0-9_\x7f-\xff]+$/', $valueword) !== 1) {
  3339. return false;
  3340. }
  3341. $result .= $valueword;
  3342. }
  3343. return $result;
  3344. }
  3345. /**
  3346. * 扩展转义路径
  3347. *
  3348. * @param string $filename
  3349. * @return string
  3350. */
  3351. private static function _path_extension($filename) {
  3352. $filepath = self::_path_file($filename);
  3353. $extension_path = isset(self::$config ['extension_path']) ? self::$config ['extension_path'] : null;
  3354. if ($filepath === null) {
  3355. if (empty($extension_path)) {
  3356. $filepath = dirname(__FILE__) . DIRECTORY_SEPARATOR . __CLASS__ . DIRECTORY_SEPARATOR . $filename;
  3357. } elseif ($extension_path [0] === '@') {
  3358. $filepath = dirname(__FILE__) . DIRECTORY_SEPARATOR . substr($extension_path, 1) . DIRECTORY_SEPARATOR . $filename;
  3359. } else {
  3360. $filepath = $extension_path . DIRECTORY_SEPARATOR . $filename;
  3361. }
  3362. }
  3363. return $filepath;
  3364. }
  3365. /**
  3366. * 模板转义路径
  3367. *
  3368. * @param string $filename
  3369. * @return string
  3370. */
  3371. private static function _path_template($filename) {
  3372. $filepath = self::_path_file($filename);
  3373. $template_path = isset(self::$config ['template_path']) ? self::$config ['template_path'] : null;
  3374. if ($filepath === null) {
  3375. if (empty($template_path)) {
  3376. $filepath = $filename;
  3377. } elseif ($template_path [0] === '@') {
  3378. $filepath = dirname(__FILE__) . DIRECTORY_SEPARATOR . substr($template_path, 1) . DIRECTORY_SEPARATOR . $filename;
  3379. } else {
  3380. $filepath = $template_path . DIRECTORY_SEPARATOR . $filename;
  3381. }
  3382. }
  3383. return $filepath;
  3384. }
  3385. /**
  3386. * 配置转义路径
  3387. *
  3388. * @param string $filename
  3389. * @return string
  3390. */
  3391. private static function _path_config($filename) {
  3392. $filepath = self::_path_file($filename);
  3393. $config_path = isset(self::$config ['config_path']) ? self::$config ['config_path'] : null;
  3394. if ($filepath === null) {
  3395. if (empty($config_path)) {
  3396. $filepath = $filename;
  3397. } elseif ($config_path [0] === '@') {
  3398. $filepath = dirname(__FILE__) . DIRECTORY_SEPARATOR . substr($config_path, 1) . DIRECTORY_SEPARATOR . $filename;
  3399. } else {
  3400. $filepath = $config_path . DIRECTORY_SEPARATOR . $filename;
  3401. }
  3402. }
  3403. return $filepath;
  3404. }
  3405. /**
  3406. * 文件转义路径
  3407. *
  3408. * @param string $filename
  3409. * @return string
  3410. */
  3411. private static function _path_file($filename) {
  3412. $first = strlen($filename) > 0 ? $filename[0] : '';
  3413. if ($first === '@') {
  3414. $filepath = dirname(__FILE__) . DIRECTORY_SEPARATOR . substr($filename, 1);
  3415. } elseif ($first === '\\' || $first === '/' || strncmp($filename, './', 2) === 0 || strncmp($filename, '.\\', 2) === 0 || strpos($filename, ':') !== false) {
  3416. $filepath = $filename;
  3417. } else {
  3418. $filepath = null;
  3419. }
  3420. return $filepath;
  3421. }
  3422. /**
  3423. * 视图全局变量
  3424. *
  3425. * @param array $global
  3426. */
  3427. private static function _view_variable($global = null) {
  3428. $variable = &self::$view;
  3429. if (!is_array($variable)) {
  3430. if (empty($variable)) {
  3431. $variable = array();
  3432. } else {
  3433. $variable = self::_init_file($variable);
  3434. if (!is_array($variable)) {
  3435. $variable = array();
  3436. }
  3437. }
  3438. $import_config = self::_init_env('view');
  3439. if ($import_config !== array()) {
  3440. $variable = array_merge($variable, $import_config);
  3441. }
  3442. }
  3443. if (is_array($global)) {
  3444. $variable = array_merge($variable, $global);
  3445. }
  3446. }
  3447. }
  3448. /**
  3449. * 执行(execute)
  3450. */
  3451. core::stub() and core::main();