core.php 148 KB

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