php_mysql.c 76 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641264226432644264526462647264826492650265126522653265426552656265726582659266026612662266326642665266626672668266926702671267226732674267526762677267826792680268126822683268426852686
  1. /*
  2. +----------------------------------------------------------------------+
  3. | PHP Version 5 |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 1997-2016 The PHP Group |
  6. +----------------------------------------------------------------------+
  7. | This source file is subject to version 3.01 of the PHP license, |
  8. | that is bundled with this package in the file LICENSE, and is |
  9. | available through the world-wide-web at the following url: |
  10. | http://www.php.net/license/3_01.txt |
  11. | If you did not receive a copy of the PHP license and are unable to |
  12. | obtain it through the world-wide-web, please send a note to |
  13. | license@php.net so we can mail you a copy immediately. |
  14. +----------------------------------------------------------------------+
  15. | Authors: Zeev Suraski <zeev@zend.com> |
  16. | Zak Greant <zak@mysql.com> |
  17. | Georg Richter <georg@php.net> |
  18. +----------------------------------------------------------------------+
  19. */
  20. /* $Id$ */
  21. /* TODO:
  22. *
  23. * ? Safe mode implementation
  24. */
  25. #ifdef HAVE_CONFIG_H
  26. # include "config.h"
  27. #endif
  28. #include "php.h"
  29. #include "php_globals.h"
  30. #include "ext/standard/info.h"
  31. #include "ext/standard/php_string.h"
  32. #include "ext/standard/basic_functions.h"
  33. #ifdef ZEND_ENGINE_2
  34. # include "zend_exceptions.h"
  35. #else
  36. /* PHP 4 compat */
  37. # define OnUpdateLong OnUpdateInt
  38. # define E_STRICT E_NOTICE
  39. #endif
  40. #if HAVE_MYSQL
  41. #ifdef PHP_WIN32
  42. # include <winsock2.h>
  43. # define signal(a, b) NULL
  44. #elif defined(NETWARE)
  45. # include <sys/socket.h>
  46. # define signal(a, b) NULL
  47. #else
  48. # if HAVE_SIGNAL_H
  49. # include <signal.h>
  50. # endif
  51. # if HAVE_SYS_TYPES_H
  52. # include <sys/types.h>
  53. # endif
  54. # include <netdb.h>
  55. # include <netinet/in.h>
  56. # if HAVE_ARPA_INET_H
  57. # include <arpa/inet.h>
  58. # endif
  59. #endif
  60. #include "php_ini.h"
  61. #include "php_mysql_structs.h"
  62. /* True globals, no need for thread safety */
  63. static int le_result, le_link, le_plink;
  64. #ifdef HAVE_MYSQL_REAL_CONNECT
  65. # ifdef HAVE_ERRMSG_H
  66. # include <errmsg.h>
  67. # endif
  68. #endif
  69. #define SAFE_STRING(s) ((s)?(s):"")
  70. #if MYSQL_VERSION_ID > 32199 || defined(MYSQL_USE_MYSQLND)
  71. # define mysql_row_length_type unsigned long
  72. # define HAVE_MYSQL_ERRNO
  73. #else
  74. # define mysql_row_length_type unsigned int
  75. # ifdef mysql_errno
  76. # define HAVE_MYSQL_ERRNO
  77. # endif
  78. #endif
  79. #if MYSQL_VERSION_ID >= 32032 || defined(MYSQL_USE_MYSQLND)
  80. #define HAVE_GETINFO_FUNCS
  81. #endif
  82. #if MYSQL_VERSION_ID > 32133 || defined(FIELD_TYPE_TINY)
  83. #define MYSQL_HAS_TINY
  84. #endif
  85. #if MYSQL_VERSION_ID >= 32200
  86. #define MYSQL_HAS_YEAR
  87. #endif
  88. #define MYSQL_ASSOC 1<<0
  89. #define MYSQL_NUM 1<<1
  90. #define MYSQL_BOTH (MYSQL_ASSOC|MYSQL_NUM)
  91. #define MYSQL_USE_RESULT 0
  92. #define MYSQL_STORE_RESULT 1
  93. #if MYSQL_VERSION_ID < 32224
  94. #define PHP_MYSQL_VALID_RESULT(mysql) \
  95. (mysql_num_fields(mysql)>0)
  96. #else
  97. #define PHP_MYSQL_VALID_RESULT(mysql) \
  98. (mysql_field_count(mysql)>0)
  99. #endif
  100. ZEND_DECLARE_MODULE_GLOBALS(mysql)
  101. static PHP_GINIT_FUNCTION(mysql);
  102. typedef struct _php_mysql_conn {
  103. MYSQL *conn;
  104. int active_result_id;
  105. int multi_query;
  106. } php_mysql_conn;
  107. #if MYSQL_VERSION_ID >= 40101
  108. #define MYSQL_DISABLE_MQ if (mysql->multi_query) { \
  109. mysql_set_server_option(mysql->conn, MYSQL_OPTION_MULTI_STATEMENTS_OFF); \
  110. mysql->multi_query = 0; \
  111. }
  112. #else
  113. #define MYSQL_DISABLE_MQ
  114. #endif
  115. /* {{{ arginfo */
  116. ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_connect, 0, 0, 0)
  117. ZEND_ARG_INFO(0, hostname)
  118. ZEND_ARG_INFO(0, username)
  119. ZEND_ARG_INFO(0, password)
  120. ZEND_ARG_INFO(0, new)
  121. ZEND_ARG_INFO(0, flags)
  122. ZEND_END_ARG_INFO()
  123. ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_pconnect, 0, 0, 0)
  124. ZEND_ARG_INFO(0, hostname)
  125. ZEND_ARG_INFO(0, username)
  126. ZEND_ARG_INFO(0, password)
  127. ZEND_ARG_INFO(0, flags)
  128. ZEND_END_ARG_INFO()
  129. ZEND_BEGIN_ARG_INFO_EX(arginfo__optional_mysql_link, 0, 0, 0)
  130. ZEND_ARG_INFO(0, link_identifier)
  131. ZEND_END_ARG_INFO()
  132. ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_select_db, 0, 0, 1)
  133. ZEND_ARG_INFO(0, database_name)
  134. ZEND_ARG_INFO(0, link_identifier)
  135. ZEND_END_ARG_INFO()
  136. ZEND_BEGIN_ARG_INFO(arginfo__void_mysql_arg, 0)
  137. ZEND_END_ARG_INFO()
  138. ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_set_charset, 0, 0, 1)
  139. ZEND_ARG_INFO(0, charset_name)
  140. ZEND_ARG_INFO(0, link_identifier)
  141. ZEND_END_ARG_INFO()
  142. ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_query, 0, 0, 1)
  143. ZEND_ARG_INFO(0, query)
  144. ZEND_ARG_INFO(0, link_identifier)
  145. ZEND_END_ARG_INFO()
  146. ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_db_query, 0, 0, 2)
  147. ZEND_ARG_INFO(0, database_name)
  148. ZEND_ARG_INFO(0, query)
  149. ZEND_ARG_INFO(0, link_identifier)
  150. ZEND_END_ARG_INFO()
  151. ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_list_fields, 0, 0, 2)
  152. ZEND_ARG_INFO(0, database_name)
  153. ZEND_ARG_INFO(0, table_name)
  154. ZEND_ARG_INFO(0, link_identifier)
  155. ZEND_END_ARG_INFO()
  156. ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_escape_string, 0, 0, 1)
  157. ZEND_ARG_INFO(0, string)
  158. ZEND_END_ARG_INFO()
  159. ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_real_escape_string, 0, 0, 1)
  160. ZEND_ARG_INFO(0, string)
  161. ZEND_ARG_INFO(0, link_identifier)
  162. ZEND_END_ARG_INFO()
  163. ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_result, 0, 0, 2)
  164. ZEND_ARG_INFO(0, result)
  165. ZEND_ARG_INFO(0, row)
  166. ZEND_ARG_INFO(0, field)
  167. ZEND_END_ARG_INFO()
  168. ZEND_BEGIN_ARG_INFO_EX(arginfo__result_mysql_arg, 0, 0, 1)
  169. ZEND_ARG_INFO(0, result)
  170. ZEND_END_ARG_INFO()
  171. ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_fetch_object, 0, 0, 1)
  172. ZEND_ARG_INFO(0, result)
  173. ZEND_ARG_INFO(0, class_name)
  174. ZEND_ARG_INFO(0, ctor_params)
  175. ZEND_END_ARG_INFO()
  176. ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_fetch_array, 0, 0, 1)
  177. ZEND_ARG_INFO(0, result)
  178. ZEND_ARG_INFO(0, result_type)
  179. ZEND_END_ARG_INFO()
  180. ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_data_seek, 0, 0, 2)
  181. ZEND_ARG_INFO(0, result)
  182. ZEND_ARG_INFO(0, row_number)
  183. ZEND_END_ARG_INFO()
  184. ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_fetch_field, 0, 0, 1)
  185. ZEND_ARG_INFO(0, result)
  186. ZEND_ARG_INFO(0, field_offset)
  187. ZEND_END_ARG_INFO()
  188. ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_field_seek, 0, 0, 2)
  189. ZEND_ARG_INFO(0, result)
  190. ZEND_ARG_INFO(0, field_offset)
  191. ZEND_END_ARG_INFO()
  192. ZEND_BEGIN_ARG_INFO_EX(arginfo_mysql_field_name, 0, 0, 2)
  193. ZEND_ARG_INFO(0, result)
  194. ZEND_ARG_INFO(0, field_index)
  195. ZEND_END_ARG_INFO()
  196. /* }}} */
  197. /* {{{ mysql_functions[]
  198. */
  199. static const zend_function_entry mysql_functions[] = {
  200. PHP_FE(mysql_connect, arginfo_mysql_connect)
  201. PHP_FE(mysql_pconnect, arginfo_mysql_pconnect)
  202. PHP_FE(mysql_close, arginfo__optional_mysql_link)
  203. PHP_FE(mysql_select_db, arginfo_mysql_select_db)
  204. #ifndef NETWARE /* The below two functions not supported on NetWare */
  205. #if MYSQL_VERSION_ID < 40000
  206. PHP_DEP_FE(mysql_create_db, arginfo_mysql_select_db)
  207. PHP_DEP_FE(mysql_drop_db, arginfo_mysql_select_db)
  208. #endif
  209. #endif /* NETWARE */
  210. PHP_FE(mysql_query, arginfo_mysql_query)
  211. PHP_FE(mysql_unbuffered_query, arginfo_mysql_query)
  212. PHP_DEP_FE(mysql_db_query, arginfo_mysql_db_query)
  213. PHP_DEP_FE(mysql_list_dbs, arginfo__optional_mysql_link)
  214. PHP_DEP_FE(mysql_list_tables, arginfo_mysql_select_db)
  215. PHP_FE(mysql_list_fields, arginfo_mysql_list_fields)
  216. PHP_FE(mysql_list_processes, arginfo__optional_mysql_link)
  217. PHP_FE(mysql_error, arginfo__optional_mysql_link)
  218. #ifdef HAVE_MYSQL_ERRNO
  219. PHP_FE(mysql_errno, arginfo__optional_mysql_link)
  220. #endif
  221. PHP_FE(mysql_affected_rows, arginfo__optional_mysql_link)
  222. PHP_FE(mysql_insert_id, arginfo__optional_mysql_link)
  223. PHP_FE(mysql_result, arginfo_mysql_result)
  224. PHP_FE(mysql_num_rows, arginfo__result_mysql_arg)
  225. PHP_FE(mysql_num_fields, arginfo__result_mysql_arg)
  226. PHP_FE(mysql_fetch_row, arginfo__result_mysql_arg)
  227. PHP_FE(mysql_fetch_array, arginfo_mysql_fetch_array)
  228. PHP_FE(mysql_fetch_assoc, arginfo__result_mysql_arg)
  229. PHP_FE(mysql_fetch_object, arginfo_mysql_fetch_object)
  230. PHP_FE(mysql_data_seek, arginfo_mysql_data_seek)
  231. PHP_FE(mysql_fetch_lengths, arginfo__result_mysql_arg)
  232. PHP_FE(mysql_fetch_field, arginfo_mysql_fetch_field)
  233. PHP_FE(mysql_field_seek, arginfo_mysql_field_seek)
  234. PHP_FE(mysql_free_result, arginfo__result_mysql_arg)
  235. PHP_FE(mysql_field_name, arginfo_mysql_field_name)
  236. PHP_FE(mysql_field_table, arginfo_mysql_field_seek)
  237. PHP_FE(mysql_field_len, arginfo_mysql_field_seek)
  238. PHP_FE(mysql_field_type, arginfo_mysql_field_seek)
  239. PHP_FE(mysql_field_flags, arginfo_mysql_field_seek)
  240. PHP_FE(mysql_escape_string, arginfo_mysql_escape_string)
  241. PHP_FE(mysql_real_escape_string, arginfo_mysql_real_escape_string)
  242. PHP_FE(mysql_stat, arginfo__optional_mysql_link)
  243. PHP_FE(mysql_thread_id, arginfo__optional_mysql_link)
  244. PHP_FE(mysql_client_encoding, arginfo__optional_mysql_link)
  245. PHP_FE(mysql_ping, arginfo__optional_mysql_link)
  246. #ifdef HAVE_GETINFO_FUNCS
  247. PHP_FE(mysql_get_client_info, arginfo__void_mysql_arg)
  248. PHP_FE(mysql_get_host_info, arginfo__optional_mysql_link)
  249. PHP_FE(mysql_get_proto_info, arginfo__optional_mysql_link)
  250. PHP_FE(mysql_get_server_info, arginfo__optional_mysql_link)
  251. #endif
  252. PHP_FE(mysql_info, arginfo__optional_mysql_link)
  253. #ifdef MYSQL_HAS_SET_CHARSET
  254. PHP_FE(mysql_set_charset, arginfo_mysql_set_charset)
  255. #endif
  256. /* for downwards compatibility */
  257. PHP_DEP_FALIAS(mysql, mysql_db_query, arginfo_mysql_db_query)
  258. PHP_DEP_FALIAS(mysql_fieldname, mysql_field_name, arginfo_mysql_field_name)
  259. PHP_DEP_FALIAS(mysql_fieldtable, mysql_field_table, arginfo_mysql_field_seek)
  260. PHP_DEP_FALIAS(mysql_fieldlen, mysql_field_len, arginfo_mysql_field_seek)
  261. PHP_DEP_FALIAS(mysql_fieldtype, mysql_field_type, arginfo_mysql_field_seek)
  262. PHP_DEP_FALIAS(mysql_fieldflags, mysql_field_flags, arginfo_mysql_field_seek)
  263. PHP_DEP_FALIAS(mysql_selectdb, mysql_select_db, arginfo_mysql_select_db)
  264. #ifndef NETWARE /* The below two functions not supported on NetWare */
  265. #if MYSQL_VERSION_ID < 40000
  266. PHP_DEP_FALIAS(mysql_createdb, mysql_create_db, arginfo_mysql_select_db)
  267. PHP_DEP_FALIAS(mysql_dropdb, mysql_drop_db, arginfo_mysql_select_db)
  268. #endif
  269. #endif /* NETWARE */
  270. PHP_DEP_FALIAS(mysql_freeresult, mysql_free_result, arginfo__result_mysql_arg)
  271. PHP_DEP_FALIAS(mysql_numfields, mysql_num_fields, arginfo__result_mysql_arg)
  272. PHP_DEP_FALIAS(mysql_numrows, mysql_num_rows, arginfo__result_mysql_arg)
  273. PHP_DEP_FALIAS(mysql_listdbs, mysql_list_dbs, arginfo__optional_mysql_link)
  274. PHP_DEP_FALIAS(mysql_listtables,mysql_list_tables, arginfo_mysql_select_db)
  275. PHP_DEP_FALIAS(mysql_listfields, mysql_list_fields, arginfo_mysql_list_fields)
  276. PHP_FALIAS(mysql_db_name, mysql_result, arginfo_mysql_result)
  277. PHP_DEP_FALIAS(mysql_dbname, mysql_result, arginfo_mysql_result)
  278. PHP_FALIAS(mysql_tablename, mysql_result, arginfo_mysql_result)
  279. PHP_FALIAS(mysql_table_name, mysql_result, arginfo_mysql_result)
  280. PHP_FE_END
  281. };
  282. /* }}} */
  283. /* Dependancies */
  284. static const zend_module_dep mysql_deps[] = {
  285. #if defined(MYSQL_USE_MYSQLND)
  286. ZEND_MOD_REQUIRED("mysqlnd")
  287. #endif
  288. ZEND_MOD_END
  289. };
  290. /* {{{ mysql_module_entry
  291. */
  292. zend_module_entry mysql_module_entry = {
  293. #if ZEND_MODULE_API_NO >= 20050922
  294. STANDARD_MODULE_HEADER_EX, NULL,
  295. mysql_deps,
  296. #elif ZEND_MODULE_API_NO >= 20010901
  297. STANDARD_MODULE_HEADER,
  298. #endif
  299. "mysql",
  300. mysql_functions,
  301. ZEND_MODULE_STARTUP_N(mysql),
  302. PHP_MSHUTDOWN(mysql),
  303. PHP_RINIT(mysql),
  304. PHP_RSHUTDOWN(mysql),
  305. PHP_MINFO(mysql),
  306. "1.0",
  307. PHP_MODULE_GLOBALS(mysql),
  308. PHP_GINIT(mysql),
  309. NULL,
  310. NULL,
  311. STANDARD_MODULE_PROPERTIES_EX
  312. };
  313. /* }}} */
  314. #ifdef COMPILE_DL_MYSQL
  315. ZEND_GET_MODULE(mysql)
  316. #endif
  317. void timeout(int sig);
  318. #define CHECK_LINK(link) { if (link==-1) { php_error_docref(NULL TSRMLS_CC, E_WARNING, "A link to the server could not be established"); RETURN_FALSE; } }
  319. #if defined(MYSQL_USE_MYSQLND)
  320. #define PHPMY_UNBUFFERED_QUERY_CHECK() \
  321. {\
  322. if (mysql->active_result_id) { \
  323. do { \
  324. int type; \
  325. MYSQL_RES *_mysql_result; \
  326. \
  327. _mysql_result = (MYSQL_RES *) zend_list_find(mysql->active_result_id, &type); \
  328. if (_mysql_result && type==le_result) { \
  329. if (mysql_result_is_unbuffered(_mysql_result) && !mysql_eof(_mysql_result)) { \
  330. php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Function called without first fetching all rows from a previous unbuffered query"); \
  331. } \
  332. zend_list_delete(mysql->active_result_id); \
  333. mysql->active_result_id = 0; \
  334. } \
  335. } while(0); \
  336. }\
  337. }
  338. #else
  339. #define PHPMY_UNBUFFERED_QUERY_CHECK() \
  340. { \
  341. if (mysql->active_result_id) { \
  342. do { \
  343. int type; \
  344. MYSQL_RES *mysql_result; \
  345. \
  346. mysql_result = (MYSQL_RES *) zend_list_find(mysql->active_result_id, &type); \
  347. if (mysql_result && type==le_result) { \
  348. if (!mysql_eof(mysql_result)) { \
  349. php_error_docref(NULL TSRMLS_CC, E_NOTICE, "Function called without first fetching all rows from a previous unbuffered query"); \
  350. while (mysql_fetch_row(mysql_result)); \
  351. } \
  352. zend_list_delete(mysql->active_result_id); \
  353. mysql->active_result_id = 0; \
  354. } \
  355. } while(0); \
  356. } \
  357. }
  358. #endif
  359. /* {{{ _free_mysql_result
  360. * This wrapper is required since mysql_free_result() returns an integer, and
  361. * thus, cannot be used directly
  362. */
  363. static void _free_mysql_result(zend_rsrc_list_entry *rsrc TSRMLS_DC)
  364. {
  365. MYSQL_RES *mysql_result = (MYSQL_RES *)rsrc->ptr;
  366. mysql_free_result(mysql_result);
  367. MySG(result_allocated)--;
  368. }
  369. /* }}} */
  370. /* {{{ php_mysql_set_default_link
  371. */
  372. static void php_mysql_set_default_link(int id TSRMLS_DC)
  373. {
  374. if (MySG(default_link) != -1) {
  375. zend_list_delete(MySG(default_link));
  376. }
  377. MySG(default_link) = id;
  378. zend_list_addref(id);
  379. }
  380. /* }}} */
  381. /* {{{ php_mysql_select_db
  382. */
  383. static int php_mysql_select_db(php_mysql_conn *mysql, char *db TSRMLS_DC)
  384. {
  385. PHPMY_UNBUFFERED_QUERY_CHECK();
  386. if (mysql_select_db(mysql->conn, db) != 0) {
  387. return 0;
  388. } else {
  389. return 1;
  390. }
  391. }
  392. /* }}} */
  393. /* {{{ _close_mysql_link
  394. */
  395. static void _close_mysql_link(zend_rsrc_list_entry *rsrc TSRMLS_DC)
  396. {
  397. php_mysql_conn *link = (php_mysql_conn *)rsrc->ptr;
  398. void (*handler) (int);
  399. handler = signal(SIGPIPE, SIG_IGN);
  400. mysql_close(link->conn);
  401. signal(SIGPIPE, handler);
  402. efree(link);
  403. MySG(num_links)--;
  404. }
  405. /* }}} */
  406. /* {{{ _close_mysql_plink
  407. */
  408. static void _close_mysql_plink(zend_rsrc_list_entry *rsrc TSRMLS_DC)
  409. {
  410. php_mysql_conn *link = (php_mysql_conn *)rsrc->ptr;
  411. void (*handler) (int);
  412. handler = signal(SIGPIPE, SIG_IGN);
  413. mysql_close(link->conn);
  414. signal(SIGPIPE, handler);
  415. free(link);
  416. MySG(num_persistent)--;
  417. MySG(num_links)--;
  418. }
  419. /* }}} */
  420. /* {{{ PHP_INI_MH
  421. */
  422. static PHP_INI_MH(OnMySQLPort)
  423. {
  424. if (new_value != NULL) { /* default port */
  425. MySG(default_port) = atoi(new_value);
  426. } else {
  427. MySG(default_port) = -1;
  428. }
  429. return SUCCESS;
  430. }
  431. /* }}} */
  432. /* {{{ PHP_INI */
  433. PHP_INI_BEGIN()
  434. STD_PHP_INI_BOOLEAN("mysql.allow_persistent", "1", PHP_INI_SYSTEM, OnUpdateLong, allow_persistent, zend_mysql_globals, mysql_globals)
  435. STD_PHP_INI_ENTRY_EX("mysql.max_persistent", "-1", PHP_INI_SYSTEM, OnUpdateLong, max_persistent, zend_mysql_globals, mysql_globals, display_link_numbers)
  436. STD_PHP_INI_ENTRY_EX("mysql.max_links", "-1", PHP_INI_SYSTEM, OnUpdateLong, max_links, zend_mysql_globals, mysql_globals, display_link_numbers)
  437. STD_PHP_INI_ENTRY("mysql.default_host", NULL, PHP_INI_ALL, OnUpdateString, default_host, zend_mysql_globals, mysql_globals)
  438. STD_PHP_INI_ENTRY("mysql.default_user", NULL, PHP_INI_ALL, OnUpdateString, default_user, zend_mysql_globals, mysql_globals)
  439. STD_PHP_INI_ENTRY("mysql.default_password", NULL, PHP_INI_ALL, OnUpdateString, default_password, zend_mysql_globals, mysql_globals)
  440. PHP_INI_ENTRY("mysql.default_port", NULL, PHP_INI_ALL, OnMySQLPort)
  441. #ifdef MYSQL_UNIX_ADDR
  442. STD_PHP_INI_ENTRY("mysql.default_socket", MYSQL_UNIX_ADDR,PHP_INI_ALL,OnUpdateStringUnempty, default_socket, zend_mysql_globals, mysql_globals)
  443. #else
  444. STD_PHP_INI_ENTRY("mysql.default_socket", NULL, PHP_INI_ALL, OnUpdateStringUnempty, default_socket, zend_mysql_globals, mysql_globals)
  445. #endif
  446. STD_PHP_INI_ENTRY("mysql.connect_timeout", "60", PHP_INI_ALL, OnUpdateLong, connect_timeout, zend_mysql_globals, mysql_globals)
  447. STD_PHP_INI_BOOLEAN("mysql.trace_mode", "0", PHP_INI_ALL, OnUpdateLong, trace_mode, zend_mysql_globals, mysql_globals)
  448. STD_PHP_INI_BOOLEAN("mysql.allow_local_infile", "1", PHP_INI_SYSTEM, OnUpdateLong, allow_local_infile, zend_mysql_globals, mysql_globals)
  449. PHP_INI_END()
  450. /* }}} */
  451. /* {{{ PHP_GINIT_FUNCTION
  452. */
  453. static PHP_GINIT_FUNCTION(mysql)
  454. {
  455. mysql_globals->num_persistent = 0;
  456. mysql_globals->default_socket = NULL;
  457. mysql_globals->default_host = NULL;
  458. mysql_globals->default_user = NULL;
  459. mysql_globals->default_password = NULL;
  460. mysql_globals->connect_errno = 0;
  461. mysql_globals->connect_error = NULL;
  462. mysql_globals->connect_timeout = 0;
  463. mysql_globals->trace_mode = 0;
  464. mysql_globals->allow_local_infile = 1;
  465. mysql_globals->result_allocated = 0;
  466. }
  467. /* }}} */
  468. #ifdef MYSQL_USE_MYSQLND
  469. #include "ext/mysqlnd/mysqlnd_reverse_api.h"
  470. static MYSQLND * mysql_convert_zv_to_mysqlnd(zval * zv TSRMLS_DC)
  471. {
  472. php_mysql_conn *mysql;
  473. if (Z_TYPE_P(zv) != IS_RESOURCE) {
  474. /* Might be nicer to check resource type, too, but ext/mysql is the only one using resources so emitting an error is not to bad, while usually this hook should be silent */
  475. return NULL;
  476. }
  477. mysql = (php_mysql_conn *)zend_fetch_resource(&zv TSRMLS_CC, -1, "MySQL-Link", NULL, 2, le_link, le_plink);
  478. if (!mysql) {
  479. return NULL;
  480. }
  481. return mysql->conn;
  482. }
  483. static MYSQLND_REVERSE_API mysql_reverse_api = {
  484. &mysql_module_entry,
  485. mysql_convert_zv_to_mysqlnd
  486. };
  487. #endif
  488. /* {{{ PHP_MINIT_FUNCTION
  489. */
  490. ZEND_MODULE_STARTUP_D(mysql)
  491. {
  492. REGISTER_INI_ENTRIES();
  493. le_result = zend_register_list_destructors_ex(_free_mysql_result, NULL, "mysql result", module_number);
  494. le_link = zend_register_list_destructors_ex(_close_mysql_link, NULL, "mysql link", module_number);
  495. le_plink = zend_register_list_destructors_ex(NULL, _close_mysql_plink, "mysql link persistent", module_number);
  496. Z_TYPE(mysql_module_entry) = type;
  497. REGISTER_LONG_CONSTANT("MYSQL_ASSOC", MYSQL_ASSOC, CONST_CS | CONST_PERSISTENT);
  498. REGISTER_LONG_CONSTANT("MYSQL_NUM", MYSQL_NUM, CONST_CS | CONST_PERSISTENT);
  499. REGISTER_LONG_CONSTANT("MYSQL_BOTH", MYSQL_BOTH, CONST_CS | CONST_PERSISTENT);
  500. REGISTER_LONG_CONSTANT("MYSQL_CLIENT_COMPRESS", CLIENT_COMPRESS, CONST_CS | CONST_PERSISTENT);
  501. #if MYSQL_VERSION_ID >= 40000
  502. REGISTER_LONG_CONSTANT("MYSQL_CLIENT_SSL", CLIENT_SSL, CONST_CS | CONST_PERSISTENT);
  503. #endif
  504. REGISTER_LONG_CONSTANT("MYSQL_CLIENT_INTERACTIVE", CLIENT_INTERACTIVE, CONST_CS | CONST_PERSISTENT);
  505. REGISTER_LONG_CONSTANT("MYSQL_CLIENT_IGNORE_SPACE", CLIENT_IGNORE_SPACE, CONST_CS | CONST_PERSISTENT);
  506. #ifndef MYSQL_USE_MYSQLND
  507. #if MYSQL_VERSION_ID >= 40000
  508. if (mysql_server_init(0, NULL, NULL)) {
  509. return FAILURE;
  510. }
  511. #endif
  512. #endif
  513. #ifdef MYSQL_USE_MYSQLND
  514. mysqlnd_reverse_api_register_api(&mysql_reverse_api TSRMLS_CC);
  515. #endif
  516. return SUCCESS;
  517. }
  518. /* }}} */
  519. /* {{{ PHP_MSHUTDOWN_FUNCTION
  520. */
  521. PHP_MSHUTDOWN_FUNCTION(mysql)
  522. {
  523. #ifndef MYSQL_USE_MYSQLND
  524. #if MYSQL_VERSION_ID >= 40000
  525. #ifdef PHP_WIN32
  526. unsigned long client_ver = mysql_get_client_version();
  527. /*
  528. Can't call mysql_server_end() multiple times prior to 5.0.46 on Windows.
  529. PHP bug#41350 MySQL bug#25621
  530. */
  531. if ((client_ver >= 50046 && client_ver < 50100) || client_ver > 50122) {
  532. mysql_server_end();
  533. }
  534. #else
  535. mysql_server_end();
  536. #endif
  537. #endif
  538. #endif
  539. UNREGISTER_INI_ENTRIES();
  540. return SUCCESS;
  541. }
  542. /* }}} */
  543. /* {{{ PHP_RINIT_FUNCTION
  544. */
  545. PHP_RINIT_FUNCTION(mysql)
  546. {
  547. #if !defined(MYSQL_USE_MYSQLND) && defined(ZTS) && MYSQL_VERSION_ID >= 40000
  548. if (mysql_thread_init()) {
  549. return FAILURE;
  550. }
  551. #endif
  552. MySG(default_link)=-1;
  553. MySG(num_links) = MySG(num_persistent);
  554. /* Reset connect error/errno on every request */
  555. MySG(connect_error) = NULL;
  556. MySG(connect_errno) =0;
  557. MySG(result_allocated) = 0;
  558. return SUCCESS;
  559. }
  560. /* }}} */
  561. #if defined(A0) && defined(MYSQL_USE_MYSQLND)
  562. static int php_mysql_persistent_helper(zend_rsrc_list_entry *le TSRMLS_DC)
  563. {
  564. if (le->type == le_plink) {
  565. mysqlnd_end_psession(((php_mysql_conn *) le->ptr)->conn);
  566. }
  567. return ZEND_HASH_APPLY_KEEP;
  568. } /* }}} */
  569. #endif
  570. /* {{{ PHP_RSHUTDOWN_FUNCTION
  571. */
  572. PHP_RSHUTDOWN_FUNCTION(mysql)
  573. {
  574. #if !defined(MYSQL_USE_MYSQLND) && defined(ZTS) && MYSQL_VERSION_ID >= 40000
  575. mysql_thread_end();
  576. #endif
  577. if (MySG(trace_mode)) {
  578. if (MySG(result_allocated)){
  579. php_error_docref("function.mysql-free-result" TSRMLS_CC, E_WARNING, "%lu result set(s) not freed. Use mysql_free_result to free result sets which were requested using mysql_query()", MySG(result_allocated));
  580. }
  581. }
  582. if (MySG(connect_error)!=NULL) {
  583. efree(MySG(connect_error));
  584. }
  585. #if defined(A0) && defined(MYSQL_USE_MYSQLND)
  586. zend_hash_apply(&EG(persistent_list), (apply_func_t) php_mysql_persistent_helper TSRMLS_CC);
  587. #endif
  588. return SUCCESS;
  589. }
  590. /* }}} */
  591. /* {{{ PHP_MINFO_FUNCTION
  592. */
  593. PHP_MINFO_FUNCTION(mysql)
  594. {
  595. char buf[32];
  596. php_info_print_table_start();
  597. php_info_print_table_header(2, "MySQL Support", "enabled");
  598. snprintf(buf, sizeof(buf), "%ld", MySG(num_persistent));
  599. php_info_print_table_row(2, "Active Persistent Links", buf);
  600. snprintf(buf, sizeof(buf), "%ld", MySG(num_links));
  601. php_info_print_table_row(2, "Active Links", buf);
  602. php_info_print_table_row(2, "Client API version", mysql_get_client_info());
  603. #if !defined (PHP_WIN32) && !defined (NETWARE) && !defined(MYSQL_USE_MYSQLND)
  604. php_info_print_table_row(2, "MYSQL_MODULE_TYPE", PHP_MYSQL_TYPE);
  605. php_info_print_table_row(2, "MYSQL_SOCKET", MYSQL_UNIX_ADDR);
  606. php_info_print_table_row(2, "MYSQL_INCLUDE", PHP_MYSQL_INCLUDE);
  607. php_info_print_table_row(2, "MYSQL_LIBS", PHP_MYSQL_LIBS);
  608. #endif
  609. php_info_print_table_end();
  610. DISPLAY_INI_ENTRIES();
  611. }
  612. /* }}} */
  613. /* {{{ php_mysql_do_connect
  614. */
  615. #define MYSQL_DO_CONNECT_CLEANUP() \
  616. if (free_host) { \
  617. efree(host); \
  618. }
  619. #define MYSQL_DO_CONNECT_RETURN_FALSE() \
  620. MYSQL_DO_CONNECT_CLEANUP(); \
  621. RETURN_FALSE;
  622. #ifdef MYSQL_USE_MYSQLND
  623. #define MYSQL_PORT 0
  624. #endif
  625. static void php_mysql_do_connect(INTERNAL_FUNCTION_PARAMETERS, int persistent)
  626. {
  627. char *user=NULL, *passwd=NULL, *host_and_port=NULL, *socket=NULL, *tmp=NULL, *host=NULL;
  628. int user_len = 0, passwd_len = 0, host_len = 0;
  629. char *hashed_details=NULL;
  630. int hashed_details_length, port = MYSQL_PORT;
  631. long client_flags = 0;
  632. php_mysql_conn *mysql=NULL;
  633. #if MYSQL_VERSION_ID <= 32230
  634. void (*handler) (int);
  635. #endif
  636. zend_bool free_host=0, new_link=0;
  637. long connect_timeout;
  638. php_error_docref(NULL TSRMLS_CC,
  639. E_DEPRECATED,
  640. "The mysql extension is deprecated and will be removed in the future: use mysqli or PDO instead");
  641. #if !defined(MYSQL_USE_MYSQLND)
  642. if ((MYSQL_VERSION_ID / 100) != (mysql_get_client_version() / 100)) {
  643. php_error_docref(NULL TSRMLS_CC, E_WARNING,
  644. "Headers and client library minor version mismatch. Headers:%d Library:%ld",
  645. MYSQL_VERSION_ID, mysql_get_client_version());
  646. }
  647. #endif
  648. connect_timeout = MySG(connect_timeout);
  649. socket = MySG(default_socket);
  650. if (MySG(default_port) < 0) {
  651. #if !defined(PHP_WIN32) && !defined(NETWARE)
  652. struct servent *serv_ptr;
  653. char *env;
  654. MySG(default_port) = MYSQL_PORT;
  655. if ((serv_ptr = getservbyname("mysql", "tcp"))) {
  656. MySG(default_port) = (uint) ntohs((ushort) serv_ptr->s_port);
  657. }
  658. if ((env = getenv("MYSQL_TCP_PORT"))) {
  659. MySG(default_port) = (uint) atoi(env);
  660. }
  661. #else
  662. MySG(default_port) = MYSQL_PORT;
  663. #endif
  664. }
  665. if (PG(sql_safe_mode)) {
  666. if (ZEND_NUM_ARGS()>0) {
  667. php_error_docref(NULL TSRMLS_CC, E_NOTICE, "SQL safe mode in effect - ignoring host/user/password information");
  668. }
  669. host_and_port=passwd=NULL;
  670. user=php_get_current_user(TSRMLS_C);
  671. hashed_details_length = spprintf(&hashed_details, 0, "mysql__%s_", user);
  672. client_flags = CLIENT_INTERACTIVE;
  673. } else {
  674. /* mysql_pconnect does not support new_link parameter */
  675. if (persistent) {
  676. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!s!s!l", &host_and_port, &host_len,
  677. &user, &user_len, &passwd, &passwd_len,
  678. &client_flags)==FAILURE) {
  679. return;
  680. }
  681. } else {
  682. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|s!s!s!bl", &host_and_port, &host_len,
  683. &user, &user_len, &passwd, &passwd_len,
  684. &new_link, &client_flags)==FAILURE) {
  685. return;
  686. }
  687. }
  688. if (!host_and_port) {
  689. host_and_port = MySG(default_host);
  690. }
  691. if (!user) {
  692. user = MySG(default_user);
  693. }
  694. if (!passwd) {
  695. passwd = MySG(default_password);
  696. passwd_len = passwd? strlen(passwd):0;
  697. }
  698. #if !defined(MYSQL_USE_MYSQLND)
  699. /* disable local infile option for open_basedir */
  700. #if PHP_API_VERSION < 20100412
  701. if (((PG(open_basedir) && PG(open_basedir)[0] != '\0') || PG(safe_mode)) && (client_flags & CLIENT_LOCAL_FILES)) {
  702. #else
  703. if ((PG(open_basedir) && PG(open_basedir)[0] != '\0') && (client_flags & CLIENT_LOCAL_FILES)) {
  704. #endif
  705. client_flags ^= CLIENT_LOCAL_FILES;
  706. }
  707. #endif
  708. #ifdef CLIENT_MULTI_RESULTS
  709. client_flags |= CLIENT_MULTI_RESULTS; /* compatibility with 5.2, see bug#50416 */
  710. #endif
  711. #ifdef CLIENT_MULTI_STATEMENTS
  712. client_flags &= ~CLIENT_MULTI_STATEMENTS; /* don't allow multi_queries via connect parameter */
  713. #endif
  714. hashed_details_length = spprintf(&hashed_details, 0, "mysql_%s_%s_%s_%ld", SAFE_STRING(host_and_port), SAFE_STRING(user), SAFE_STRING(passwd), client_flags);
  715. }
  716. /* We cannot use mysql_port anymore in windows, need to use
  717. * mysql_real_connect() to set the port.
  718. */
  719. if (host_and_port && (tmp=strchr(host_and_port, ':'))) {
  720. host = estrndup(host_and_port, tmp-host_and_port);
  721. free_host = 1;
  722. tmp++;
  723. if (tmp[0] != '/') {
  724. port = atoi(tmp);
  725. if ((tmp=strchr(tmp, ':'))) {
  726. tmp++;
  727. socket=tmp;
  728. }
  729. } else {
  730. socket = tmp;
  731. }
  732. } else {
  733. host = host_and_port;
  734. port = MySG(default_port);
  735. }
  736. #if MYSQL_VERSION_ID < 32200
  737. mysql_port = port;
  738. #endif
  739. if (!MySG(allow_persistent)) {
  740. persistent=0;
  741. }
  742. if (persistent) {
  743. zend_rsrc_list_entry *le;
  744. /* try to find if we already have this link in our persistent list */
  745. if (zend_hash_find(&EG(persistent_list), hashed_details, hashed_details_length+1, (void **) &le)==FAILURE) { /* we don't */
  746. zend_rsrc_list_entry new_le;
  747. if (MySG(max_links) != -1 && MySG(num_links) >= MySG(max_links)) {
  748. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Too many open links (%ld)", MySG(num_links));
  749. efree(hashed_details);
  750. MYSQL_DO_CONNECT_RETURN_FALSE();
  751. }
  752. if (MySG(max_persistent) != -1 && MySG(num_persistent) >= MySG(max_persistent)) {
  753. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Too many open persistent links (%ld)", MySG(num_persistent));
  754. efree(hashed_details);
  755. MYSQL_DO_CONNECT_RETURN_FALSE();
  756. }
  757. /* create the link */
  758. mysql = (php_mysql_conn *) malloc(sizeof(php_mysql_conn));
  759. if (!mysql) {
  760. php_error_docref(NULL TSRMLS_CC, E_ERROR, "Out of memory while allocating memory for a persistent link");
  761. }
  762. mysql->active_result_id = 0;
  763. #ifdef CLIENT_MULTI_STATEMENTS
  764. mysql->multi_query = client_flags & CLIENT_MULTI_STATEMENTS? 1:0;
  765. #else
  766. mysql->multi_query = 0;
  767. #endif
  768. #ifndef MYSQL_USE_MYSQLND
  769. mysql->conn = mysql_init(NULL);
  770. #else
  771. mysql->conn = mysqlnd_init(MYSQLND_CLIENT_KNOWS_RSET_COPY_DATA, persistent);
  772. #endif
  773. if (connect_timeout != -1) {
  774. mysql_options(mysql->conn, MYSQL_OPT_CONNECT_TIMEOUT, (const char *)&connect_timeout);
  775. }
  776. #ifndef MYSQL_USE_MYSQLND
  777. if (mysql_real_connect(mysql->conn, host, user, passwd, NULL, port, socket, client_flags)==NULL)
  778. #else
  779. if (mysqlnd_connect(mysql->conn, host, user, passwd, passwd_len, NULL, 0, port, socket, client_flags, MYSQLND_CLIENT_KNOWS_RSET_COPY_DATA TSRMLS_CC) == NULL)
  780. #endif
  781. {
  782. /* Populate connect error globals so that the error functions can read them */
  783. if (MySG(connect_error) != NULL) {
  784. efree(MySG(connect_error));
  785. }
  786. MySG(connect_error) = estrdup(mysql_error(mysql->conn));
  787. php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", MySG(connect_error));
  788. #if defined(HAVE_MYSQL_ERRNO)
  789. MySG(connect_errno) = mysql_errno(mysql->conn);
  790. #endif
  791. free(mysql);
  792. efree(hashed_details);
  793. MYSQL_DO_CONNECT_RETURN_FALSE();
  794. }
  795. mysql_options(mysql->conn, MYSQL_OPT_LOCAL_INFILE, (char *)&MySG(allow_local_infile));
  796. /* hash it up */
  797. Z_TYPE(new_le) = le_plink;
  798. new_le.ptr = mysql;
  799. if (zend_hash_update(&EG(persistent_list), hashed_details, hashed_details_length+1, (void *) &new_le, sizeof(zend_rsrc_list_entry), NULL)==FAILURE) {
  800. free(mysql);
  801. efree(hashed_details);
  802. MYSQL_DO_CONNECT_RETURN_FALSE();
  803. }
  804. MySG(num_persistent)++;
  805. MySG(num_links)++;
  806. } else { /* The link is in our list of persistent connections */
  807. if (Z_TYPE_P(le) != le_plink) {
  808. MYSQL_DO_CONNECT_RETURN_FALSE();
  809. }
  810. mysql = (php_mysql_conn *) le->ptr;
  811. mysql->active_result_id = 0;
  812. #ifdef CLIENT_MULTI_STATEMENTS
  813. mysql->multi_query = client_flags & CLIENT_MULTI_STATEMENTS? 1:0;
  814. #else
  815. mysql->multi_query = 0;
  816. #endif
  817. /* ensure that the link did not die */
  818. #if defined(A0) && MYSQL_USE_MYSQLND
  819. mysqlnd_end_psession(mysql->conn);
  820. #endif
  821. if (mysql_ping(mysql->conn)) {
  822. if (mysql_errno(mysql->conn) == 2006) {
  823. #ifndef MYSQL_USE_MYSQLND
  824. if (mysql_real_connect(mysql->conn, host, user, passwd, NULL, port, socket, client_flags)==NULL)
  825. #else
  826. if (mysqlnd_connect(mysql->conn, host, user, passwd, passwd_len, NULL, 0, port, socket, client_flags, MYSQLND_CLIENT_KNOWS_RSET_COPY_DATA TSRMLS_CC) == NULL)
  827. #endif
  828. {
  829. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Link to server lost, unable to reconnect");
  830. zend_hash_del(&EG(persistent_list), hashed_details, hashed_details_length+1);
  831. efree(hashed_details);
  832. MYSQL_DO_CONNECT_RETURN_FALSE();
  833. }
  834. mysql_options(mysql->conn, MYSQL_OPT_LOCAL_INFILE, (char *)&MySG(allow_local_infile));
  835. }
  836. } else {
  837. #ifdef MYSQL_USE_MYSQLND
  838. mysqlnd_restart_psession(mysql->conn);
  839. #endif
  840. }
  841. }
  842. ZEND_REGISTER_RESOURCE(return_value, mysql, le_plink);
  843. } else { /* non persistent */
  844. zend_rsrc_list_entry *index_ptr, new_index_ptr;
  845. /* first we check the hash for the hashed_details key. if it exists,
  846. * it should point us to the right offset where the actual mysql link sits.
  847. * if it doesn't, open a new mysql link, add it to the resource list,
  848. * and add a pointer to it with hashed_details as the key.
  849. */
  850. if (!new_link && zend_hash_find(&EG(regular_list), hashed_details, hashed_details_length+1,(void **) &index_ptr)==SUCCESS) {
  851. int type;
  852. long link;
  853. void *ptr;
  854. if (Z_TYPE_P(index_ptr) != le_index_ptr) {
  855. MYSQL_DO_CONNECT_RETURN_FALSE();
  856. }
  857. link = (long) index_ptr->ptr;
  858. ptr = zend_list_find(link,&type); /* check if the link is still there */
  859. if (ptr && (type==le_link || type==le_plink)) {
  860. zend_list_addref(link);
  861. Z_LVAL_P(return_value) = link;
  862. php_mysql_set_default_link(link TSRMLS_CC);
  863. Z_TYPE_P(return_value) = IS_RESOURCE;
  864. efree(hashed_details);
  865. MYSQL_DO_CONNECT_CLEANUP();
  866. return;
  867. } else {
  868. zend_hash_del(&EG(regular_list), hashed_details, hashed_details_length+1);
  869. }
  870. }
  871. if (MySG(max_links) != -1 && MySG(num_links) >= MySG(max_links)) {
  872. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Too many open links (%ld)", MySG(num_links));
  873. efree(hashed_details);
  874. MYSQL_DO_CONNECT_RETURN_FALSE();
  875. }
  876. mysql = (php_mysql_conn *) emalloc(sizeof(php_mysql_conn));
  877. mysql->active_result_id = 0;
  878. #ifdef CLIENT_MULTI_STATEMENTS
  879. mysql->multi_query = 1;
  880. #endif
  881. #ifndef MYSQL_USE_MYSQLND
  882. mysql->conn = mysql_init(NULL);
  883. #else
  884. mysql->conn = mysqlnd_init(MYSQLND_CLIENT_KNOWS_RSET_COPY_DATA, persistent);
  885. #endif
  886. if (!mysql->conn) {
  887. MySG(connect_error) = estrdup("OOM");
  888. php_error_docref(NULL TSRMLS_CC, E_WARNING, "OOM");
  889. efree(hashed_details);
  890. efree(mysql);
  891. MYSQL_DO_CONNECT_RETURN_FALSE();
  892. }
  893. if (connect_timeout != -1) {
  894. mysql_options(mysql->conn, MYSQL_OPT_CONNECT_TIMEOUT, (const char *)&connect_timeout);
  895. }
  896. #ifndef MYSQL_USE_MYSQLND
  897. if (mysql_real_connect(mysql->conn, host, user, passwd, NULL, port, socket, client_flags)==NULL)
  898. #else
  899. if (mysqlnd_connect(mysql->conn, host, user, passwd, passwd_len, NULL, 0, port, socket, client_flags, MYSQLND_CLIENT_KNOWS_RSET_COPY_DATA TSRMLS_CC) == NULL)
  900. #endif
  901. {
  902. /* Populate connect error globals so that the error functions can read them */
  903. if (MySG(connect_error) != NULL) {
  904. efree(MySG(connect_error));
  905. }
  906. MySG(connect_error) = estrdup(mysql_error(mysql->conn));
  907. php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s", MySG(connect_error));
  908. #if defined(HAVE_MYSQL_ERRNO)
  909. MySG(connect_errno) = mysql_errno(mysql->conn);
  910. #endif
  911. /* free mysql structure */
  912. #ifdef MYSQL_USE_MYSQLND
  913. mysqlnd_close(mysql->conn, MYSQLND_CLOSE_DISCONNECTED);
  914. #endif
  915. efree(hashed_details);
  916. efree(mysql);
  917. MYSQL_DO_CONNECT_RETURN_FALSE();
  918. }
  919. mysql_options(mysql->conn, MYSQL_OPT_LOCAL_INFILE, (char *)&MySG(allow_local_infile));
  920. /* add it to the list */
  921. ZEND_REGISTER_RESOURCE(return_value, mysql, le_link);
  922. /* add it to the hash */
  923. new_index_ptr.ptr = (void *) Z_LVAL_P(return_value);
  924. Z_TYPE(new_index_ptr) = le_index_ptr;
  925. if (zend_hash_update(&EG(regular_list), hashed_details, hashed_details_length+1,(void *) &new_index_ptr, sizeof(zend_rsrc_list_entry), NULL)==FAILURE) {
  926. efree(hashed_details);
  927. MYSQL_DO_CONNECT_RETURN_FALSE();
  928. }
  929. MySG(num_links)++;
  930. }
  931. efree(hashed_details);
  932. php_mysql_set_default_link(Z_LVAL_P(return_value) TSRMLS_CC);
  933. MYSQL_DO_CONNECT_CLEANUP();
  934. }
  935. /* }}} */
  936. /* {{{ php_mysql_get_default_link
  937. */
  938. static int php_mysql_get_default_link(INTERNAL_FUNCTION_PARAMETERS)
  939. {
  940. if (MySG(default_link)==-1) { /* no link opened yet, implicitly open one */
  941. ht = 0;
  942. php_mysql_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
  943. }
  944. return MySG(default_link);
  945. }
  946. /* }}} */
  947. /* {{{ proto resource mysql_connect([string hostname[:port][:/path/to/socket] [, string username [, string password [, bool new [, int flags]]]]])
  948. Opens a connection to a MySQL Server */
  949. PHP_FUNCTION(mysql_connect)
  950. {
  951. php_mysql_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0);
  952. }
  953. /* }}} */
  954. /* {{{ proto resource mysql_pconnect([string hostname[:port][:/path/to/socket] [, string username [, string password [, int flags]]]])
  955. Opens a persistent connection to a MySQL Server */
  956. PHP_FUNCTION(mysql_pconnect)
  957. {
  958. php_mysql_do_connect(INTERNAL_FUNCTION_PARAM_PASSTHRU, 1);
  959. }
  960. /* }}} */
  961. /* {{{ proto bool mysql_close([int link_identifier])
  962. Close a MySQL connection */
  963. PHP_FUNCTION(mysql_close)
  964. {
  965. int resource_id;
  966. zval *mysql_link=NULL;
  967. php_mysql_conn *mysql;
  968. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
  969. return;
  970. }
  971. if (mysql_link) {
  972. ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, -1, "MySQL-Link", le_link, le_plink);
  973. } else {
  974. ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, NULL, MySG(default_link), "MySQL-Link", le_link, le_plink);
  975. }
  976. resource_id = mysql_link ? Z_RESVAL_P(mysql_link) : MySG(default_link);
  977. PHPMY_UNBUFFERED_QUERY_CHECK();
  978. #ifdef MYSQL_USE_MYSQLND
  979. {
  980. int tmp;
  981. if ((mysql = zend_list_find(resource_id, &tmp)) && tmp == le_plink) {
  982. mysqlnd_end_psession(mysql->conn);
  983. }
  984. }
  985. #endif
  986. zend_list_delete(resource_id);
  987. if (!mysql_link
  988. || (mysql_link && Z_RESVAL_P(mysql_link)==MySG(default_link))) {
  989. MySG(default_link) = -1;
  990. if (mysql_link) {
  991. /* on an explicit close of the default connection it had a refcount of 2 so we need one more call */
  992. zend_list_delete(resource_id);
  993. }
  994. }
  995. RETURN_TRUE;
  996. }
  997. /* }}} */
  998. /* {{{ proto bool mysql_select_db(string database_name [, int link_identifier])
  999. Selects a MySQL database */
  1000. PHP_FUNCTION(mysql_select_db)
  1001. {
  1002. char *db;
  1003. int db_len;
  1004. zval *mysql_link = NULL;
  1005. int id = -1;
  1006. php_mysql_conn *mysql;
  1007. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &db, &db_len, &mysql_link) == FAILURE) {
  1008. return;
  1009. }
  1010. if (!mysql_link) {
  1011. id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
  1012. CHECK_LINK(id);
  1013. }
  1014. ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
  1015. if (php_mysql_select_db(mysql, db TSRMLS_CC)) {
  1016. RETURN_TRUE;
  1017. } else {
  1018. RETURN_FALSE;
  1019. }
  1020. }
  1021. /* }}} */
  1022. #ifdef HAVE_GETINFO_FUNCS
  1023. /* {{{ proto string mysql_get_client_info(void)
  1024. Returns a string that represents the client library version */
  1025. PHP_FUNCTION(mysql_get_client_info)
  1026. {
  1027. if (zend_parse_parameters_none() == FAILURE) {
  1028. return;
  1029. }
  1030. RETURN_STRING((char *)mysql_get_client_info(),1);
  1031. }
  1032. /* }}} */
  1033. /* {{{ proto string mysql_get_host_info([int link_identifier])
  1034. Returns a string describing the type of connection in use, including the server host name */
  1035. PHP_FUNCTION(mysql_get_host_info)
  1036. {
  1037. zval *mysql_link = NULL;
  1038. int id = -1;
  1039. php_mysql_conn *mysql;
  1040. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
  1041. return;
  1042. }
  1043. if (!mysql_link) {
  1044. id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
  1045. CHECK_LINK(id);
  1046. }
  1047. ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
  1048. RETURN_STRING((char *)mysql_get_host_info(mysql->conn),1);
  1049. }
  1050. /* }}} */
  1051. /* {{{ proto int mysql_get_proto_info([int link_identifier])
  1052. Returns the protocol version used by current connection */
  1053. PHP_FUNCTION(mysql_get_proto_info)
  1054. {
  1055. zval *mysql_link = NULL;
  1056. int id = -1;
  1057. php_mysql_conn *mysql;
  1058. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
  1059. return;
  1060. }
  1061. if (!mysql_link) {
  1062. id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
  1063. CHECK_LINK(id);
  1064. }
  1065. ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
  1066. RETURN_LONG(mysql_get_proto_info(mysql->conn));
  1067. }
  1068. /* }}} */
  1069. /* {{{ proto string mysql_get_server_info([int link_identifier])
  1070. Returns a string that represents the server version number */
  1071. PHP_FUNCTION(mysql_get_server_info)
  1072. {
  1073. zval *mysql_link = NULL;
  1074. int id = -1;
  1075. php_mysql_conn *mysql;
  1076. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
  1077. return;
  1078. }
  1079. if (!mysql_link) {
  1080. id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
  1081. CHECK_LINK(id);
  1082. }
  1083. ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
  1084. RETURN_STRING((char *)mysql_get_server_info(mysql->conn),1);
  1085. }
  1086. /* }}} */
  1087. /* {{{ proto string mysql_info([int link_identifier])
  1088. Returns a string containing information about the most recent query */
  1089. PHP_FUNCTION(mysql_info)
  1090. {
  1091. zval *mysql_link = NULL;
  1092. int id = -1;
  1093. char *str;
  1094. php_mysql_conn *mysql;
  1095. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
  1096. return;
  1097. }
  1098. if (ZEND_NUM_ARGS() == 0) {
  1099. id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
  1100. CHECK_LINK(id);
  1101. }
  1102. ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
  1103. if ((str = (char *)mysql_info(mysql->conn))) {
  1104. RETURN_STRING(str,1);
  1105. } else {
  1106. RETURN_FALSE;
  1107. }
  1108. }
  1109. /* }}} */
  1110. /* {{{ proto int mysql_thread_id([int link_identifier])
  1111. Returns the thread id of current connection */
  1112. PHP_FUNCTION(mysql_thread_id)
  1113. {
  1114. zval *mysql_link = NULL;
  1115. int id = -1;
  1116. php_mysql_conn *mysql;
  1117. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
  1118. return;
  1119. }
  1120. if (ZEND_NUM_ARGS() == 0) {
  1121. id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
  1122. CHECK_LINK(id);
  1123. }
  1124. ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
  1125. RETURN_LONG((long) mysql_thread_id(mysql->conn));
  1126. }
  1127. /* }}} */
  1128. /* {{{ proto string mysql_stat([int link_identifier])
  1129. Returns a string containing status information */
  1130. PHP_FUNCTION(mysql_stat)
  1131. {
  1132. zval *mysql_link = NULL;
  1133. int id = -1;
  1134. php_mysql_conn *mysql;
  1135. char *stat;
  1136. #ifdef MYSQL_USE_MYSQLND
  1137. uint stat_len;
  1138. #endif
  1139. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
  1140. return;
  1141. }
  1142. if (ZEND_NUM_ARGS() == 0) {
  1143. id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
  1144. CHECK_LINK(id);
  1145. }
  1146. ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
  1147. PHPMY_UNBUFFERED_QUERY_CHECK();
  1148. #ifndef MYSQL_USE_MYSQLND
  1149. if ((stat = (char *)mysql_stat(mysql->conn))) {
  1150. RETURN_STRING(stat, 1);
  1151. #else
  1152. if (mysqlnd_stat(mysql->conn, &stat, &stat_len) == PASS) {
  1153. RETURN_STRINGL(stat, stat_len, 0);
  1154. #endif
  1155. } else {
  1156. RETURN_FALSE;
  1157. }
  1158. }
  1159. /* }}} */
  1160. /* {{{ proto string mysql_client_encoding([int link_identifier])
  1161. Returns the default character set for the current connection */
  1162. PHP_FUNCTION(mysql_client_encoding)
  1163. {
  1164. zval *mysql_link = NULL;
  1165. int id = -1;
  1166. php_mysql_conn *mysql;
  1167. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
  1168. return;
  1169. }
  1170. if (ZEND_NUM_ARGS() == 0) {
  1171. id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
  1172. CHECK_LINK(id);
  1173. }
  1174. ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
  1175. RETURN_STRING((char *)mysql_character_set_name(mysql->conn), 1);
  1176. }
  1177. /* }}} */
  1178. #endif
  1179. #ifdef MYSQL_HAS_SET_CHARSET
  1180. /* {{{ proto bool mysql_set_charset(string csname [, int link_identifier])
  1181. sets client character set */
  1182. PHP_FUNCTION(mysql_set_charset)
  1183. {
  1184. zval *mysql_link = NULL;
  1185. char *csname;
  1186. int id = -1, csname_len;
  1187. php_mysql_conn *mysql;
  1188. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &csname, &csname_len, &mysql_link) == FAILURE) {
  1189. return;
  1190. }
  1191. if (ZEND_NUM_ARGS() == 1) {
  1192. id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
  1193. CHECK_LINK(id);
  1194. }
  1195. ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
  1196. if (!mysql_set_character_set(mysql->conn, csname)) {
  1197. RETURN_TRUE;
  1198. } else {
  1199. RETURN_FALSE;
  1200. }
  1201. }
  1202. /* }}} */
  1203. #endif
  1204. #ifndef NETWARE /* The below two functions not supported on NetWare */
  1205. #if MYSQL_VERSION_ID < 40000
  1206. /* {{{ proto bool mysql_create_db(string database_name [, int link_identifier])
  1207. Create a MySQL database */
  1208. PHP_FUNCTION(mysql_create_db)
  1209. {
  1210. char *db;
  1211. int db_len;
  1212. zval *mysql_link = NULL;
  1213. int id = -1;
  1214. php_mysql_conn *mysql;
  1215. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &db, &db_len, &mysql_link) == FAILURE) {
  1216. return;
  1217. }
  1218. if (!mysql_link) {
  1219. id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
  1220. CHECK_LINK(id);
  1221. }
  1222. ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
  1223. PHPMY_UNBUFFERED_QUERY_CHECK();
  1224. if (mysql_create_db(mysql->conn, db)==0) {
  1225. RETURN_TRUE;
  1226. } else {
  1227. RETURN_FALSE;
  1228. }
  1229. }
  1230. /* }}} */
  1231. /* {{{ proto bool mysql_drop_db(string database_name [, int link_identifier])
  1232. Drops (delete) a MySQL database */
  1233. PHP_FUNCTION(mysql_drop_db)
  1234. {
  1235. char *db;
  1236. int db_len;
  1237. zval *mysql_link = NULL;
  1238. int id = -1;
  1239. php_mysql_conn *mysql;
  1240. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &db, &db_len, &mysql_link) == FAILURE) {
  1241. return;
  1242. }
  1243. if (!mysql_link) {
  1244. id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
  1245. CHECK_LINK(id);
  1246. }
  1247. ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
  1248. if (mysql_drop_db(mysql->conn, db)==0) {
  1249. RETURN_TRUE;
  1250. } else {
  1251. RETURN_FALSE;
  1252. }
  1253. }
  1254. /* }}} */
  1255. #endif
  1256. #endif /* NETWARE */
  1257. /* {{{ php_mysql_do_query_general
  1258. */
  1259. static void php_mysql_do_query_general(char *query, int query_len, zval *mysql_link, int link_id, char *db, int use_store, zval *return_value TSRMLS_DC)
  1260. {
  1261. php_mysql_conn *mysql;
  1262. MYSQL_RES *mysql_result;
  1263. ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, link_id, "MySQL-Link", le_link, le_plink);
  1264. if (db) {
  1265. if (!php_mysql_select_db(mysql, db TSRMLS_CC)) {
  1266. RETURN_FALSE;
  1267. }
  1268. }
  1269. PHPMY_UNBUFFERED_QUERY_CHECK();
  1270. MYSQL_DISABLE_MQ;
  1271. #ifndef MYSQL_USE_MYSQLND
  1272. /* check explain */
  1273. if (MySG(trace_mode)) {
  1274. if (!strncasecmp("select", query, 6)){
  1275. MYSQL_ROW row;
  1276. char *newquery;
  1277. int newql = spprintf (&newquery, 0, "EXPLAIN %s", query);
  1278. mysql_real_query(mysql->conn, newquery, newql);
  1279. efree (newquery);
  1280. if (mysql_errno(mysql->conn)) {
  1281. php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(mysql->conn));
  1282. RETURN_FALSE;
  1283. }
  1284. else {
  1285. mysql_result = mysql_use_result(mysql->conn);
  1286. while ((row = mysql_fetch_row(mysql_result))) {
  1287. if (!strcmp("ALL", row[1])) {
  1288. php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "Your query requires a full tablescan (table %s, %s rows affected). Use EXPLAIN to optimize your query.", row[0], row[6]);
  1289. } else if (!strcmp("INDEX", row[1])) {
  1290. php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "Your query requires a full indexscan (table %s, %s rows affected). Use EXPLAIN to optimize your query.", row[0], row[6]);
  1291. }
  1292. }
  1293. mysql_free_result(mysql_result);
  1294. }
  1295. }
  1296. } /* end explain */
  1297. #endif
  1298. /* mysql_query is binary unsafe, use mysql_real_query */
  1299. #if MYSQL_VERSION_ID > 32199
  1300. if (mysql_real_query(mysql->conn, query, query_len)!=0) {
  1301. /* check possible error */
  1302. if (MySG(trace_mode)){
  1303. if (mysql_errno(mysql->conn)){
  1304. php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(mysql->conn));
  1305. }
  1306. }
  1307. RETURN_FALSE;
  1308. }
  1309. #else
  1310. if (mysql_query(mysql->conn, query)!=0) {
  1311. /* check possible error */
  1312. if (MySG(trace_mode)){
  1313. if (mysql_errno(mysql->conn)){
  1314. php_error_docref("http://www.mysql.com/doc" TSRMLS_CC, E_WARNING, "%s", mysql_error(mysql->conn));
  1315. }
  1316. }
  1317. RETURN_FALSE;
  1318. }
  1319. #endif
  1320. if(use_store == MYSQL_USE_RESULT) {
  1321. mysql_result=mysql_use_result(mysql->conn);
  1322. } else {
  1323. mysql_result=mysql_store_result(mysql->conn);
  1324. }
  1325. if (!mysql_result) {
  1326. if (PHP_MYSQL_VALID_RESULT(mysql->conn)) { /* query should have returned rows */
  1327. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to save result set");
  1328. RETURN_FALSE;
  1329. } else {
  1330. RETURN_TRUE;
  1331. }
  1332. }
  1333. MySG(result_allocated)++;
  1334. ZEND_REGISTER_RESOURCE(return_value, mysql_result, le_result);
  1335. if (use_store == MYSQL_USE_RESULT) {
  1336. mysql->active_result_id = Z_LVAL_P(return_value);
  1337. }
  1338. }
  1339. /* }}} */
  1340. /* {{{ php_mysql_do_query
  1341. */
  1342. static void php_mysql_do_query(INTERNAL_FUNCTION_PARAMETERS, int use_store)
  1343. {
  1344. char *query;
  1345. int query_len;
  1346. zval *mysql_link = NULL;
  1347. int id = -1;
  1348. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &query, &query_len, &mysql_link) == FAILURE) {
  1349. return;
  1350. }
  1351. if (!mysql_link) {
  1352. id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
  1353. CHECK_LINK(id);
  1354. }
  1355. php_mysql_do_query_general(query, query_len, mysql_link, id, NULL, use_store, return_value TSRMLS_CC);
  1356. }
  1357. /* }}} */
  1358. /* {{{ proto resource mysql_query(string query [, int link_identifier])
  1359. Sends an SQL query to MySQL */
  1360. PHP_FUNCTION(mysql_query)
  1361. {
  1362. php_mysql_do_query(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQL_STORE_RESULT);
  1363. }
  1364. /* }}} */
  1365. /* {{{ proto resource mysql_unbuffered_query(string query [, int link_identifier])
  1366. Sends an SQL query to MySQL, without fetching and buffering the result rows */
  1367. PHP_FUNCTION(mysql_unbuffered_query)
  1368. {
  1369. php_mysql_do_query(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQL_USE_RESULT);
  1370. }
  1371. /* }}} */
  1372. /* {{{ proto resource mysql_db_query(string database_name, string query [, int link_identifier])
  1373. Sends an SQL query to MySQL */
  1374. PHP_FUNCTION(mysql_db_query)
  1375. {
  1376. char *db, *query;
  1377. int db_len, query_len;
  1378. zval *mysql_link = NULL;
  1379. int id = -1;
  1380. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|r", &db, &db_len, &query, &query_len, &mysql_link) == FAILURE) {
  1381. return;
  1382. }
  1383. if (!mysql_link) {
  1384. id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
  1385. CHECK_LINK(id);
  1386. }
  1387. php_error_docref(NULL TSRMLS_CC, E_DEPRECATED, "This function is deprecated; use mysql_query() instead");
  1388. php_mysql_do_query_general(query, query_len, mysql_link, id, db, MYSQL_STORE_RESULT, return_value TSRMLS_CC);
  1389. }
  1390. /* }}} */
  1391. /* {{{ proto resource mysql_list_dbs([int link_identifier])
  1392. List databases available on a MySQL server */
  1393. PHP_FUNCTION(mysql_list_dbs)
  1394. {
  1395. zval *mysql_link = NULL;
  1396. int id = -1;
  1397. php_mysql_conn *mysql;
  1398. MYSQL_RES *mysql_result;
  1399. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
  1400. return;
  1401. }
  1402. if (!mysql_link) {
  1403. id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
  1404. CHECK_LINK(id);
  1405. }
  1406. php_error_docref(NULL TSRMLS_CC, E_DEPRECATED, "This function is deprecated; use mysql_query() with SHOW DATABASES instead");
  1407. ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
  1408. PHPMY_UNBUFFERED_QUERY_CHECK();
  1409. if ((mysql_result=mysql_list_dbs(mysql->conn, NULL))==NULL) {
  1410. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to save MySQL query result");
  1411. RETURN_FALSE;
  1412. }
  1413. MySG(result_allocated)++;
  1414. ZEND_REGISTER_RESOURCE(return_value, mysql_result, le_result);
  1415. }
  1416. /* }}} */
  1417. /* {{{ proto resource mysql_list_tables(string database_name [, int link_identifier])
  1418. List tables in a MySQL database */
  1419. PHP_FUNCTION(mysql_list_tables)
  1420. {
  1421. char *db;
  1422. int db_len;
  1423. zval *mysql_link = NULL;
  1424. int id = -1;
  1425. php_mysql_conn *mysql;
  1426. MYSQL_RES *mysql_result;
  1427. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &db, &db_len, &mysql_link) == FAILURE) {
  1428. return;
  1429. }
  1430. if (!mysql_link) {
  1431. id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
  1432. CHECK_LINK(id);
  1433. }
  1434. ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
  1435. if (!php_mysql_select_db(mysql, db TSRMLS_CC)) {
  1436. RETURN_FALSE;
  1437. }
  1438. PHPMY_UNBUFFERED_QUERY_CHECK();
  1439. if ((mysql_result=mysql_list_tables(mysql->conn, NULL))==NULL) {
  1440. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to save MySQL query result");
  1441. RETURN_FALSE;
  1442. }
  1443. MySG(result_allocated)++;
  1444. ZEND_REGISTER_RESOURCE(return_value, mysql_result, le_result);
  1445. }
  1446. /* }}} */
  1447. /* {{{ proto resource mysql_list_fields(string database_name, string table_name [, int link_identifier])
  1448. List MySQL result fields */
  1449. PHP_FUNCTION(mysql_list_fields)
  1450. {
  1451. char *db, *table;
  1452. int db_len, table_len;
  1453. zval *mysql_link = NULL;
  1454. int id = -1;
  1455. php_mysql_conn *mysql;
  1456. MYSQL_RES *mysql_result;
  1457. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "ss|r", &db, &db_len, &table, &table_len, &mysql_link) == FAILURE) {
  1458. return;
  1459. }
  1460. if (!mysql_link) {
  1461. id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
  1462. CHECK_LINK(id);
  1463. }
  1464. ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
  1465. if (!php_mysql_select_db(mysql, db TSRMLS_CC)) {
  1466. RETURN_FALSE;
  1467. }
  1468. PHPMY_UNBUFFERED_QUERY_CHECK();
  1469. if ((mysql_result=mysql_list_fields(mysql->conn, table, NULL))==NULL) {
  1470. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to save MySQL query result");
  1471. RETURN_FALSE;
  1472. }
  1473. MySG(result_allocated)++;
  1474. ZEND_REGISTER_RESOURCE(return_value, mysql_result, le_result);
  1475. }
  1476. /* }}} */
  1477. /* {{{ proto resource mysql_list_processes([int link_identifier])
  1478. Returns a result set describing the current server threads */
  1479. PHP_FUNCTION(mysql_list_processes)
  1480. {
  1481. zval *mysql_link = NULL;
  1482. int id = -1;
  1483. php_mysql_conn *mysql;
  1484. MYSQL_RES *mysql_result;
  1485. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
  1486. return;
  1487. }
  1488. if (ZEND_NUM_ARGS() == 0) {
  1489. id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
  1490. CHECK_LINK(id);
  1491. }
  1492. ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
  1493. PHPMY_UNBUFFERED_QUERY_CHECK();
  1494. mysql_result = mysql_list_processes(mysql->conn);
  1495. if (mysql_result == NULL) {
  1496. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to save MySQL query result");
  1497. RETURN_FALSE;
  1498. }
  1499. MySG(result_allocated)++;
  1500. ZEND_REGISTER_RESOURCE(return_value, mysql_result, le_result);
  1501. }
  1502. /* }}} */
  1503. /* {{{ proto string mysql_error([int link_identifier])
  1504. Returns the text of the error message from previous MySQL operation */
  1505. PHP_FUNCTION(mysql_error)
  1506. {
  1507. zval *mysql_link = NULL;
  1508. int id = -1;
  1509. php_mysql_conn *mysql;
  1510. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
  1511. return;
  1512. }
  1513. if (!mysql_link) {
  1514. id = MySG(default_link);
  1515. if (id==-1) {
  1516. if (MySG(connect_error)!=NULL){
  1517. RETURN_STRING(MySG(connect_error),1);
  1518. } else {
  1519. RETURN_FALSE;
  1520. }
  1521. }
  1522. }
  1523. ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
  1524. RETURN_STRING((char *)mysql_error(mysql->conn), 1);
  1525. }
  1526. /* }}} */
  1527. /* {{{ proto int mysql_errno([int link_identifier])
  1528. Returns the number of the error message from previous MySQL operation */
  1529. #ifdef HAVE_MYSQL_ERRNO
  1530. PHP_FUNCTION(mysql_errno)
  1531. {
  1532. zval *mysql_link = NULL;
  1533. int id = -1;
  1534. php_mysql_conn *mysql;
  1535. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
  1536. return;
  1537. }
  1538. if (!mysql_link) {
  1539. id = MySG(default_link);
  1540. if (id==-1) {
  1541. if (MySG(connect_errno)!=0){
  1542. RETURN_LONG(MySG(connect_errno));
  1543. } else {
  1544. RETURN_FALSE;
  1545. }
  1546. }
  1547. }
  1548. ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
  1549. RETURN_LONG(mysql_errno(mysql->conn));
  1550. }
  1551. #endif
  1552. /* }}} */
  1553. /* {{{ proto int mysql_affected_rows([int link_identifier])
  1554. Gets number of affected rows in previous MySQL operation */
  1555. PHP_FUNCTION(mysql_affected_rows)
  1556. {
  1557. zval *mysql_link = NULL;
  1558. int id = -1;
  1559. php_mysql_conn *mysql;
  1560. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
  1561. return;
  1562. }
  1563. if (!mysql_link) {
  1564. id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
  1565. CHECK_LINK(id);
  1566. }
  1567. ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
  1568. /* conversion from int64 to long happing here */
  1569. Z_LVAL_P(return_value) = (long) mysql_affected_rows(mysql->conn);
  1570. Z_TYPE_P(return_value) = IS_LONG;
  1571. }
  1572. /* }}} */
  1573. /* {{{ proto string mysql_escape_string(string to_be_escaped)
  1574. Escape string for mysql query */
  1575. PHP_FUNCTION(mysql_escape_string)
  1576. {
  1577. char *str;
  1578. int str_len;
  1579. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s", &str, &str_len) == FAILURE) {
  1580. return;
  1581. }
  1582. /* assume worst case situation, which is 2x of the original string.
  1583. * we don't realloc() down to the real size since it'd most probably not
  1584. * be worth it
  1585. */
  1586. Z_STRVAL_P(return_value) = (char *) safe_emalloc(str_len, 2, 1);
  1587. Z_STRLEN_P(return_value) = mysql_escape_string(Z_STRVAL_P(return_value), str, str_len);
  1588. Z_TYPE_P(return_value) = IS_STRING;
  1589. php_error_docref("function.mysql-real-escape-string" TSRMLS_CC, E_DEPRECATED, "This function is deprecated; use mysql_real_escape_string() instead.");
  1590. }
  1591. /* }}} */
  1592. /* {{{ proto string mysql_real_escape_string(string to_be_escaped [, int link_identifier])
  1593. Escape special characters in a string for use in a SQL statement, taking into account the current charset of the connection */
  1594. PHP_FUNCTION(mysql_real_escape_string)
  1595. {
  1596. zval *mysql_link = NULL;
  1597. char *str;
  1598. char *new_str;
  1599. int id = -1, str_len, new_str_len;
  1600. php_mysql_conn *mysql;
  1601. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "s|r", &str, &str_len, &mysql_link) == FAILURE) {
  1602. return;
  1603. }
  1604. if (ZEND_NUM_ARGS() == 1) {
  1605. id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
  1606. CHECK_LINK(id);
  1607. }
  1608. ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
  1609. new_str = safe_emalloc(str_len, 2, 1);
  1610. new_str_len = mysql_real_escape_string(mysql->conn, new_str, str, str_len);
  1611. new_str = erealloc(new_str, new_str_len + 1);
  1612. RETURN_STRINGL(new_str, new_str_len, 0);
  1613. }
  1614. /* }}} */
  1615. /* {{{ proto int mysql_insert_id([int link_identifier])
  1616. Gets the ID generated from the previous INSERT operation */
  1617. PHP_FUNCTION(mysql_insert_id)
  1618. {
  1619. zval *mysql_link = NULL;
  1620. int id = -1;
  1621. php_mysql_conn *mysql;
  1622. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|r", &mysql_link) == FAILURE) {
  1623. return;
  1624. }
  1625. if (!mysql_link) {
  1626. id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
  1627. CHECK_LINK(id);
  1628. }
  1629. ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
  1630. /* conversion from int64 to long happing here */
  1631. Z_LVAL_P(return_value) = (long) mysql_insert_id(mysql->conn);
  1632. Z_TYPE_P(return_value) = IS_LONG;
  1633. }
  1634. /* }}} */
  1635. /* {{{ proto mixed mysql_result(resource result, int row [, mixed field])
  1636. Gets result data */
  1637. PHP_FUNCTION(mysql_result)
  1638. {
  1639. zval *result, *field=NULL;
  1640. long row;
  1641. MYSQL_RES *mysql_result;
  1642. #ifndef MYSQL_USE_MYSQLND
  1643. MYSQL_ROW sql_row;
  1644. mysql_row_length_type *sql_row_lengths;
  1645. #endif
  1646. int field_offset=0;
  1647. /*
  1648. johannes TODO:
  1649. Do 2 zend_parse_parameters calls instead of type "z" and switch below
  1650. Q: String or long first?
  1651. */
  1652. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl|z", &result, &row, &field) == FAILURE) {
  1653. return;
  1654. }
  1655. ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &result, -1, "MySQL result", le_result);
  1656. if (row<0 || row>=(int)mysql_num_rows(mysql_result)) {
  1657. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Unable to jump to row %ld on MySQL result index %ld", row, Z_LVAL_P(result));
  1658. RETURN_FALSE;
  1659. }
  1660. mysql_data_seek(mysql_result, row);
  1661. if (field) {
  1662. switch(Z_TYPE_P(field)) {
  1663. case IS_STRING: {
  1664. int i=0;
  1665. const MYSQL_FIELD *tmp_field;
  1666. char *table_name, *field_name, *tmp;
  1667. if ((tmp=strchr(Z_STRVAL_P(field), '.'))) {
  1668. table_name = estrndup(Z_STRVAL_P(field), tmp-Z_STRVAL_P(field));
  1669. field_name = estrdup(tmp+1);
  1670. } else {
  1671. table_name = NULL;
  1672. field_name = estrndup(Z_STRVAL_P(field),Z_STRLEN_P(field));
  1673. }
  1674. mysql_field_seek(mysql_result, 0);
  1675. while ((tmp_field=mysql_fetch_field(mysql_result))) {
  1676. if ((!table_name || !strcasecmp(tmp_field->table, table_name)) && !strcasecmp(tmp_field->name, field_name)) {
  1677. field_offset = i;
  1678. break;
  1679. }
  1680. i++;
  1681. }
  1682. if (!tmp_field) { /* no match found */
  1683. php_error_docref(NULL TSRMLS_CC, E_WARNING, "%s%s%s not found in MySQL result index %ld",
  1684. (table_name?table_name:""), (table_name?".":""), field_name, Z_LVAL_P(result));
  1685. efree(field_name);
  1686. if (table_name) {
  1687. efree(table_name);
  1688. }
  1689. RETURN_FALSE;
  1690. }
  1691. efree(field_name);
  1692. if (table_name) {
  1693. efree(table_name);
  1694. }
  1695. }
  1696. break;
  1697. default:
  1698. convert_to_long_ex(&field);
  1699. field_offset = Z_LVAL_P(field);
  1700. if (field_offset<0 || field_offset>=(int)mysql_num_fields(mysql_result)) {
  1701. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Bad column offset specified");
  1702. RETURN_FALSE;
  1703. }
  1704. break;
  1705. }
  1706. }
  1707. #ifndef MYSQL_USE_MYSQLND
  1708. if ((sql_row=mysql_fetch_row(mysql_result))==NULL
  1709. || (sql_row_lengths=mysql_fetch_lengths(mysql_result))==NULL) { /* shouldn't happen? */
  1710. RETURN_FALSE;
  1711. }
  1712. if (sql_row[field_offset]) {
  1713. Z_TYPE_P(return_value) = IS_STRING;
  1714. #if PHP_API_VERSION < 20100412
  1715. if (PG(magic_quotes_runtime)) {
  1716. Z_STRVAL_P(return_value) = php_addslashes(sql_row[field_offset], sql_row_lengths[field_offset],&Z_STRLEN_P(return_value), 0 TSRMLS_CC);
  1717. } else {
  1718. #endif
  1719. Z_STRLEN_P(return_value) = sql_row_lengths[field_offset];
  1720. Z_STRVAL_P(return_value) = (char *) safe_estrndup(sql_row[field_offset], Z_STRLEN_P(return_value));
  1721. #if PHP_API_VERSION < 20100412
  1722. }
  1723. #endif
  1724. } else {
  1725. Z_TYPE_P(return_value) = IS_NULL;
  1726. }
  1727. #else
  1728. mysqlnd_result_fetch_field_data(mysql_result, field_offset, return_value);
  1729. #endif
  1730. }
  1731. /* }}} */
  1732. /* {{{ proto int mysql_num_rows(resource result)
  1733. Gets number of rows in a result */
  1734. PHP_FUNCTION(mysql_num_rows)
  1735. {
  1736. zval *result;
  1737. MYSQL_RES *mysql_result;
  1738. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &result) == FAILURE) {
  1739. return;
  1740. }
  1741. ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &result, -1, "MySQL result", le_result);
  1742. /* conversion from int64 to long happing here */
  1743. Z_LVAL_P(return_value) = (long) mysql_num_rows(mysql_result);
  1744. Z_TYPE_P(return_value) = IS_LONG;
  1745. }
  1746. /* }}} */
  1747. /* {{{ proto int mysql_num_fields(resource result)
  1748. Gets number of fields in a result */
  1749. PHP_FUNCTION(mysql_num_fields)
  1750. {
  1751. zval *result;
  1752. MYSQL_RES *mysql_result;
  1753. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &result) == FAILURE) {
  1754. return;
  1755. }
  1756. ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &result, -1, "MySQL result", le_result);
  1757. Z_LVAL_P(return_value) = mysql_num_fields(mysql_result);
  1758. Z_TYPE_P(return_value) = IS_LONG;
  1759. }
  1760. /* }}} */
  1761. /* {{{ php_mysql_fetch_hash
  1762. */
  1763. static void php_mysql_fetch_hash(INTERNAL_FUNCTION_PARAMETERS, long result_type, int expected_args, int into_object)
  1764. {
  1765. MYSQL_RES *mysql_result;
  1766. zval *res, *ctor_params = NULL;
  1767. zend_class_entry *ce = NULL;
  1768. #ifndef MYSQL_USE_MYSQLND
  1769. int i;
  1770. MYSQL_FIELD *mysql_field;
  1771. MYSQL_ROW mysql_row;
  1772. mysql_row_length_type *mysql_row_lengths;
  1773. #endif
  1774. #ifdef ZEND_ENGINE_2
  1775. if (into_object) {
  1776. char *class_name = NULL;
  1777. int class_name_len = 0;
  1778. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "z|sz", &res, &class_name, &class_name_len, &ctor_params) == FAILURE) {
  1779. return;
  1780. }
  1781. if (ZEND_NUM_ARGS() < 2) {
  1782. ce = zend_standard_class_def;
  1783. } else {
  1784. ce = zend_fetch_class(class_name, class_name_len, ZEND_FETCH_CLASS_AUTO TSRMLS_CC);
  1785. }
  1786. if (!ce) {
  1787. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Could not find class '%s'", class_name);
  1788. return;
  1789. }
  1790. result_type = MYSQL_ASSOC;
  1791. } else
  1792. #endif
  1793. {
  1794. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &res, &result_type) == FAILURE) {
  1795. return;
  1796. }
  1797. if (!result_type) {
  1798. /* result_type might have been set outside, so only overwrite when not set */
  1799. result_type = MYSQL_BOTH;
  1800. }
  1801. }
  1802. if (result_type & ~MYSQL_BOTH) {
  1803. php_error_docref(NULL TSRMLS_CC, E_WARNING, "The result type should be either MYSQL_NUM, MYSQL_ASSOC or MYSQL_BOTH");
  1804. result_type = MYSQL_BOTH;
  1805. }
  1806. ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &res, -1, "MySQL result", le_result);
  1807. #ifndef MYSQL_USE_MYSQLND
  1808. if ((mysql_row = mysql_fetch_row(mysql_result)) == NULL ||
  1809. (mysql_row_lengths = mysql_fetch_lengths(mysql_result)) == NULL) {
  1810. RETURN_FALSE;
  1811. }
  1812. array_init(return_value);
  1813. mysql_field_seek(mysql_result, 0);
  1814. for (mysql_field = mysql_fetch_field(mysql_result), i = 0;
  1815. mysql_field;
  1816. mysql_field = mysql_fetch_field(mysql_result), i++)
  1817. {
  1818. if (mysql_row[i]) {
  1819. zval *data;
  1820. MAKE_STD_ZVAL(data);
  1821. #if PHP_API_VERSION < 20100412
  1822. if (PG(magic_quotes_runtime)) {
  1823. Z_TYPE_P(data) = IS_STRING;
  1824. Z_STRVAL_P(data) = php_addslashes(mysql_row[i], mysql_row_lengths[i], &Z_STRLEN_P(data), 0 TSRMLS_CC);
  1825. } else {
  1826. #endif
  1827. ZVAL_STRINGL(data, mysql_row[i], mysql_row_lengths[i], 1);
  1828. #if PHP_API_VERSION < 20100412
  1829. }
  1830. #endif
  1831. if (result_type & MYSQL_NUM) {
  1832. add_index_zval(return_value, i, data);
  1833. }
  1834. if (result_type & MYSQL_ASSOC) {
  1835. if (result_type & MYSQL_NUM) {
  1836. Z_ADDREF_P(data);
  1837. }
  1838. add_assoc_zval(return_value, mysql_field->name, data);
  1839. }
  1840. } else {
  1841. /* NULL value. */
  1842. if (result_type & MYSQL_NUM) {
  1843. add_index_null(return_value, i);
  1844. }
  1845. if (result_type & MYSQL_ASSOC) {
  1846. add_assoc_null(return_value, mysql_field->name);
  1847. }
  1848. }
  1849. }
  1850. #else
  1851. mysqlnd_fetch_into(mysql_result, ((result_type & MYSQL_NUM)? MYSQLND_FETCH_NUM:0) | ((result_type & MYSQL_ASSOC)? MYSQLND_FETCH_ASSOC:0), return_value, MYSQLND_MYSQL);
  1852. #endif
  1853. #ifdef ZEND_ENGINE_2
  1854. /* mysqlnd might return FALSE if no more rows */
  1855. if (into_object && Z_TYPE_P(return_value) != IS_BOOL) {
  1856. zval dataset = *return_value;
  1857. zend_fcall_info fci;
  1858. zend_fcall_info_cache fcc;
  1859. zval *retval_ptr;
  1860. object_and_properties_init(return_value, ce, NULL);
  1861. zend_merge_properties(return_value, Z_ARRVAL(dataset), 1 TSRMLS_CC);
  1862. if (ce->constructor) {
  1863. fci.size = sizeof(fci);
  1864. fci.function_table = &ce->function_table;
  1865. fci.function_name = NULL;
  1866. fci.symbol_table = NULL;
  1867. fci.object_ptr = return_value;
  1868. fci.retval_ptr_ptr = &retval_ptr;
  1869. fci.params = NULL;
  1870. fci.param_count = 0;
  1871. fci.no_separation = 1;
  1872. if (ctor_params && Z_TYPE_P(ctor_params) != IS_NULL) {
  1873. if (zend_fcall_info_args(&fci, ctor_params TSRMLS_CC) == FAILURE) {
  1874. /* Two problems why we throw exceptions here: PHP is typeless
  1875. * and hence passing one argument that's not an array could be
  1876. * by mistake and the other way round is possible, too. The
  1877. * single value is an array. Also we'd have to make that one
  1878. * argument passed by reference.
  1879. */
  1880. zend_throw_exception(zend_exception_get_default(TSRMLS_C), "Parameter ctor_params must be an array", 0 TSRMLS_CC);
  1881. return;
  1882. }
  1883. }
  1884. fcc.initialized = 1;
  1885. fcc.function_handler = ce->constructor;
  1886. fcc.calling_scope = EG(scope);
  1887. fcc.called_scope = Z_OBJCE_P(return_value);
  1888. fcc.object_ptr = return_value;
  1889. if (zend_call_function(&fci, &fcc TSRMLS_CC) == FAILURE) {
  1890. zend_throw_exception_ex(zend_exception_get_default(TSRMLS_C), 0 TSRMLS_CC, "Could not execute %s::%s()", ce->name, ce->constructor->common.function_name);
  1891. } else {
  1892. if (retval_ptr) {
  1893. zval_ptr_dtor(&retval_ptr);
  1894. }
  1895. }
  1896. if (fci.params) {
  1897. efree(fci.params);
  1898. }
  1899. } else if (ctor_params) {
  1900. zend_throw_exception_ex(zend_exception_get_default(TSRMLS_C), 0 TSRMLS_CC, "Class %s does not have a constructor hence you cannot use ctor_params", ce->name);
  1901. }
  1902. }
  1903. #endif
  1904. }
  1905. /* }}} */
  1906. /* {{{ proto array mysql_fetch_row(resource result)
  1907. Gets a result row as an enumerated array */
  1908. PHP_FUNCTION(mysql_fetch_row)
  1909. {
  1910. php_mysql_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQL_NUM, 1, 0);
  1911. }
  1912. /* }}} */
  1913. /* {{{ proto object mysql_fetch_object(resource result [, string class_name [, NULL|array ctor_params]])
  1914. Fetch a result row as an object */
  1915. PHP_FUNCTION(mysql_fetch_object)
  1916. {
  1917. php_mysql_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQL_ASSOC, 2, 1);
  1918. if (Z_TYPE_P(return_value) == IS_ARRAY) {
  1919. object_and_properties_init(return_value, ZEND_STANDARD_CLASS_DEF_PTR, Z_ARRVAL_P(return_value));
  1920. }
  1921. }
  1922. /* }}} */
  1923. /* {{{ proto array mysql_fetch_array(resource result [, int result_type])
  1924. Fetch a result row as an array (associative, numeric or both) */
  1925. PHP_FUNCTION(mysql_fetch_array)
  1926. {
  1927. php_mysql_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0, 2, 0);
  1928. }
  1929. /* }}} */
  1930. /* {{{ proto array mysql_fetch_assoc(resource result)
  1931. Fetch a result row as an associative array */
  1932. PHP_FUNCTION(mysql_fetch_assoc)
  1933. {
  1934. php_mysql_fetch_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQL_ASSOC, 1, 0);
  1935. }
  1936. /* }}} */
  1937. /* {{{ proto bool mysql_data_seek(resource result, int row_number)
  1938. Move internal result pointer */
  1939. PHP_FUNCTION(mysql_data_seek)
  1940. {
  1941. zval *result;
  1942. long offset;
  1943. MYSQL_RES *mysql_result;
  1944. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &result, &offset)) {
  1945. return;
  1946. }
  1947. ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &result, -1, "MySQL result", le_result);
  1948. if (offset<0 || offset>=(int)mysql_num_rows(mysql_result)) {
  1949. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Offset %ld is invalid for MySQL result index %ld (or the query data is unbuffered)", offset, Z_LVAL_P(result));
  1950. RETURN_FALSE;
  1951. }
  1952. mysql_data_seek(mysql_result, offset);
  1953. RETURN_TRUE;
  1954. }
  1955. /* }}} */
  1956. /* {{{ proto array mysql_fetch_lengths(resource result)
  1957. Gets max data size of each column in a result */
  1958. PHP_FUNCTION(mysql_fetch_lengths)
  1959. {
  1960. zval *result;
  1961. MYSQL_RES *mysql_result;
  1962. mysql_row_length_type *lengths;
  1963. int num_fields;
  1964. int i;
  1965. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &result) == FAILURE) {
  1966. return;
  1967. }
  1968. ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &result, -1, "MySQL result", le_result);
  1969. if ((lengths=mysql_fetch_lengths(mysql_result))==NULL) {
  1970. RETURN_FALSE;
  1971. }
  1972. array_init(return_value);
  1973. num_fields = mysql_num_fields(mysql_result);
  1974. for (i=0; i<num_fields; i++) {
  1975. add_index_long(return_value, i, lengths[i]);
  1976. }
  1977. }
  1978. /* }}} */
  1979. /* {{{ php_mysql_get_field_name
  1980. */
  1981. static char *php_mysql_get_field_name(int field_type)
  1982. {
  1983. switch(field_type) {
  1984. case FIELD_TYPE_STRING:
  1985. case FIELD_TYPE_VAR_STRING:
  1986. return "string";
  1987. break;
  1988. #if MYSQL_VERSION_ID > 50002 || defined(MYSQL_USE_MYSQLND)
  1989. case MYSQL_TYPE_BIT:
  1990. #endif
  1991. #ifdef MYSQL_HAS_TINY
  1992. case FIELD_TYPE_TINY:
  1993. #endif
  1994. case FIELD_TYPE_SHORT:
  1995. case FIELD_TYPE_LONG:
  1996. case FIELD_TYPE_LONGLONG:
  1997. case FIELD_TYPE_INT24:
  1998. return "int";
  1999. break;
  2000. case FIELD_TYPE_FLOAT:
  2001. case FIELD_TYPE_DOUBLE:
  2002. case FIELD_TYPE_DECIMAL:
  2003. #ifdef FIELD_TYPE_NEWDECIMAL
  2004. case FIELD_TYPE_NEWDECIMAL:
  2005. #endif
  2006. return "real";
  2007. break;
  2008. case FIELD_TYPE_TIMESTAMP:
  2009. return "timestamp";
  2010. break;
  2011. #ifdef MYSQL_HAS_YEAR
  2012. case FIELD_TYPE_YEAR:
  2013. return "year";
  2014. break;
  2015. #endif
  2016. case FIELD_TYPE_DATE:
  2017. #ifdef FIELD_TYPE_NEWDATE
  2018. case FIELD_TYPE_NEWDATE:
  2019. #endif
  2020. return "date";
  2021. break;
  2022. case FIELD_TYPE_TIME:
  2023. return "time";
  2024. break;
  2025. case FIELD_TYPE_SET:
  2026. return "set";
  2027. break;
  2028. case FIELD_TYPE_ENUM:
  2029. return "enum";
  2030. break;
  2031. #ifdef FIELD_TYPE_GEOMETRY
  2032. case FIELD_TYPE_GEOMETRY:
  2033. return "geometry";
  2034. break;
  2035. #endif
  2036. case FIELD_TYPE_DATETIME:
  2037. return "datetime";
  2038. break;
  2039. case FIELD_TYPE_TINY_BLOB:
  2040. case FIELD_TYPE_MEDIUM_BLOB:
  2041. case FIELD_TYPE_LONG_BLOB:
  2042. case FIELD_TYPE_BLOB:
  2043. return "blob";
  2044. break;
  2045. case FIELD_TYPE_NULL:
  2046. return "null";
  2047. break;
  2048. default:
  2049. return "unknown";
  2050. break;
  2051. }
  2052. }
  2053. /* }}} */
  2054. /* {{{ proto object mysql_fetch_field(resource result [, int field_offset])
  2055. Gets column information from a result and return as an object */
  2056. PHP_FUNCTION(mysql_fetch_field)
  2057. {
  2058. zval *result;
  2059. long field=0;
  2060. MYSQL_RES *mysql_result;
  2061. const MYSQL_FIELD *mysql_field;
  2062. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r|l", &result, &field) == FAILURE) {
  2063. return;
  2064. }
  2065. ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &result, -1, "MySQL result", le_result);
  2066. if (ZEND_NUM_ARGS() > 1) {
  2067. if (field<0 || field>=(int)mysql_num_fields(mysql_result)) {
  2068. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Bad field offset");
  2069. RETURN_FALSE;
  2070. }
  2071. mysql_field_seek(mysql_result, field);
  2072. }
  2073. if ((mysql_field=mysql_fetch_field(mysql_result))==NULL) {
  2074. RETURN_FALSE;
  2075. }
  2076. object_init(return_value);
  2077. add_property_string(return_value, "name",(mysql_field->name?mysql_field->name:""), 1);
  2078. add_property_string(return_value, "table",(mysql_field->table?mysql_field->table:""), 1);
  2079. add_property_string(return_value, "def",(mysql_field->def?mysql_field->def:""), 1);
  2080. add_property_long(return_value, "max_length", mysql_field->max_length);
  2081. add_property_long(return_value, "not_null", IS_NOT_NULL(mysql_field->flags)?1:0);
  2082. add_property_long(return_value, "primary_key", IS_PRI_KEY(mysql_field->flags)?1:0);
  2083. add_property_long(return_value, "multiple_key",(mysql_field->flags&MULTIPLE_KEY_FLAG?1:0));
  2084. add_property_long(return_value, "unique_key",(mysql_field->flags&UNIQUE_KEY_FLAG?1:0));
  2085. add_property_long(return_value, "numeric", IS_NUM(Z_TYPE_P(mysql_field))?1:0);
  2086. add_property_long(return_value, "blob", IS_BLOB(mysql_field->flags)?1:0);
  2087. add_property_string(return_value, "type", php_mysql_get_field_name(Z_TYPE_P(mysql_field)), 1);
  2088. add_property_long(return_value, "unsigned",(mysql_field->flags&UNSIGNED_FLAG?1:0));
  2089. add_property_long(return_value, "zerofill",(mysql_field->flags&ZEROFILL_FLAG?1:0));
  2090. }
  2091. /* }}} */
  2092. /* {{{ proto bool mysql_field_seek(resource result, int field_offset)
  2093. Sets result pointer to a specific field offset */
  2094. PHP_FUNCTION(mysql_field_seek)
  2095. {
  2096. zval *result;
  2097. long offset;
  2098. MYSQL_RES *mysql_result;
  2099. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &result, &offset) == FAILURE) {
  2100. return;
  2101. }
  2102. ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &result, -1, "MySQL result", le_result);
  2103. if (offset<0 || offset>=(int)mysql_num_fields(mysql_result)) {
  2104. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Field %ld is invalid for MySQL result index %ld", offset, Z_LVAL_P(result));
  2105. RETURN_FALSE;
  2106. }
  2107. mysql_field_seek(mysql_result, offset);
  2108. RETURN_TRUE;
  2109. }
  2110. /* }}} */
  2111. #define PHP_MYSQL_FIELD_NAME 1
  2112. #define PHP_MYSQL_FIELD_TABLE 2
  2113. #define PHP_MYSQL_FIELD_LEN 3
  2114. #define PHP_MYSQL_FIELD_TYPE 4
  2115. #define PHP_MYSQL_FIELD_FLAGS 5
  2116. /* {{{ php_mysql_field_info
  2117. */
  2118. static void php_mysql_field_info(INTERNAL_FUNCTION_PARAMETERS, int entry_type)
  2119. {
  2120. zval *result;
  2121. long field;
  2122. MYSQL_RES *mysql_result;
  2123. const MYSQL_FIELD *mysql_field = {0};
  2124. char buf[512];
  2125. int len;
  2126. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "rl", &result, &field) == FAILURE) {
  2127. return;
  2128. }
  2129. ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &result, -1, "MySQL result", le_result);
  2130. if (field<0 || field>=(int)mysql_num_fields(mysql_result)) {
  2131. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Field %ld is invalid for MySQL result index %ld", field, Z_LVAL_P(result));
  2132. RETURN_FALSE;
  2133. }
  2134. mysql_field_seek(mysql_result, field);
  2135. if ((mysql_field=mysql_fetch_field(mysql_result))==NULL) {
  2136. RETURN_FALSE;
  2137. }
  2138. switch (entry_type) {
  2139. case PHP_MYSQL_FIELD_NAME:
  2140. Z_STRLEN_P(return_value) = strlen(mysql_field->name);
  2141. Z_STRVAL_P(return_value) = estrndup(mysql_field->name, Z_STRLEN_P(return_value));
  2142. Z_TYPE_P(return_value) = IS_STRING;
  2143. break;
  2144. case PHP_MYSQL_FIELD_TABLE:
  2145. Z_STRLEN_P(return_value) = strlen(mysql_field->table);
  2146. Z_STRVAL_P(return_value) = estrndup(mysql_field->table, Z_STRLEN_P(return_value));
  2147. Z_TYPE_P(return_value) = IS_STRING;
  2148. break;
  2149. case PHP_MYSQL_FIELD_LEN:
  2150. Z_LVAL_P(return_value) = mysql_field->length;
  2151. Z_TYPE_P(return_value) = IS_LONG;
  2152. break;
  2153. case PHP_MYSQL_FIELD_TYPE:
  2154. Z_STRVAL_P(return_value) = php_mysql_get_field_name(Z_TYPE_P(mysql_field));
  2155. Z_STRLEN_P(return_value) = strlen(Z_STRVAL_P(return_value));
  2156. Z_STRVAL_P(return_value) = estrndup(Z_STRVAL_P(return_value), Z_STRLEN_P(return_value));
  2157. Z_TYPE_P(return_value) = IS_STRING;
  2158. break;
  2159. case PHP_MYSQL_FIELD_FLAGS:
  2160. memcpy(buf, "", sizeof(""));
  2161. #ifdef IS_NOT_NULL
  2162. if (IS_NOT_NULL(mysql_field->flags)) {
  2163. strcat(buf, "not_null ");
  2164. }
  2165. #endif
  2166. #ifdef IS_PRI_KEY
  2167. if (IS_PRI_KEY(mysql_field->flags)) {
  2168. strcat(buf, "primary_key ");
  2169. }
  2170. #endif
  2171. #ifdef UNIQUE_KEY_FLAG
  2172. if (mysql_field->flags&UNIQUE_KEY_FLAG) {
  2173. strcat(buf, "unique_key ");
  2174. }
  2175. #endif
  2176. #ifdef MULTIPLE_KEY_FLAG
  2177. if (mysql_field->flags&MULTIPLE_KEY_FLAG) {
  2178. strcat(buf, "multiple_key ");
  2179. }
  2180. #endif
  2181. #ifdef IS_BLOB
  2182. if (IS_BLOB(mysql_field->flags)) {
  2183. strcat(buf, "blob ");
  2184. }
  2185. #endif
  2186. #ifdef UNSIGNED_FLAG
  2187. if (mysql_field->flags&UNSIGNED_FLAG) {
  2188. strcat(buf, "unsigned ");
  2189. }
  2190. #endif
  2191. #ifdef ZEROFILL_FLAG
  2192. if (mysql_field->flags&ZEROFILL_FLAG) {
  2193. strcat(buf, "zerofill ");
  2194. }
  2195. #endif
  2196. #ifdef BINARY_FLAG
  2197. if (mysql_field->flags&BINARY_FLAG) {
  2198. strcat(buf, "binary ");
  2199. }
  2200. #endif
  2201. #ifdef ENUM_FLAG
  2202. if (mysql_field->flags&ENUM_FLAG) {
  2203. strcat(buf, "enum ");
  2204. }
  2205. #endif
  2206. #ifdef SET_FLAG
  2207. if (mysql_field->flags&SET_FLAG) {
  2208. strcat(buf, "set ");
  2209. }
  2210. #endif
  2211. #ifdef AUTO_INCREMENT_FLAG
  2212. if (mysql_field->flags&AUTO_INCREMENT_FLAG) {
  2213. strcat(buf, "auto_increment ");
  2214. }
  2215. #endif
  2216. #ifdef TIMESTAMP_FLAG
  2217. if (mysql_field->flags&TIMESTAMP_FLAG) {
  2218. strcat(buf, "timestamp ");
  2219. }
  2220. #endif
  2221. len = strlen(buf);
  2222. /* remove trailing space, if present */
  2223. if (len && buf[len-1] == ' ') {
  2224. buf[len-1] = 0;
  2225. len--;
  2226. }
  2227. Z_STRLEN_P(return_value) = len;
  2228. Z_STRVAL_P(return_value) = estrndup(buf, len);
  2229. Z_TYPE_P(return_value) = IS_STRING;
  2230. break;
  2231. default:
  2232. RETURN_FALSE;
  2233. }
  2234. }
  2235. /* }}} */
  2236. /* {{{ proto string mysql_field_name(resource result, int field_index)
  2237. Gets the name of the specified field in a result */
  2238. PHP_FUNCTION(mysql_field_name)
  2239. {
  2240. php_mysql_field_info(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_MYSQL_FIELD_NAME);
  2241. }
  2242. /* }}} */
  2243. /* {{{ proto string mysql_field_table(resource result, int field_offset)
  2244. Gets name of the table the specified field is in */
  2245. PHP_FUNCTION(mysql_field_table)
  2246. {
  2247. php_mysql_field_info(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_MYSQL_FIELD_TABLE);
  2248. }
  2249. /* }}} */
  2250. /* {{{ proto int mysql_field_len(resource result, int field_offset)
  2251. Returns the length of the specified field */
  2252. PHP_FUNCTION(mysql_field_len)
  2253. {
  2254. php_mysql_field_info(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_MYSQL_FIELD_LEN);
  2255. }
  2256. /* }}} */
  2257. /* {{{ proto string mysql_field_type(resource result, int field_offset)
  2258. Gets the type of the specified field in a result */
  2259. PHP_FUNCTION(mysql_field_type)
  2260. {
  2261. php_mysql_field_info(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_MYSQL_FIELD_TYPE);
  2262. }
  2263. /* }}} */
  2264. /* {{{ proto string mysql_field_flags(resource result, int field_offset)
  2265. Gets the flags associated with the specified field in a result */
  2266. PHP_FUNCTION(mysql_field_flags)
  2267. {
  2268. php_mysql_field_info(INTERNAL_FUNCTION_PARAM_PASSTHRU, PHP_MYSQL_FIELD_FLAGS);
  2269. }
  2270. /* }}} */
  2271. /* {{{ proto bool mysql_free_result(resource result)
  2272. Free result memory */
  2273. PHP_FUNCTION(mysql_free_result)
  2274. {
  2275. zval *result;
  2276. MYSQL_RES *mysql_result;
  2277. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &result) == FAILURE) {
  2278. return;
  2279. }
  2280. if (Z_LVAL_P(result)==0) {
  2281. RETURN_FALSE;
  2282. }
  2283. ZEND_FETCH_RESOURCE(mysql_result, MYSQL_RES *, &result, -1, "MySQL result", le_result);
  2284. zend_list_delete(Z_LVAL_P(result));
  2285. RETURN_TRUE;
  2286. }
  2287. /* }}} */
  2288. /* {{{ proto bool mysql_ping([int link_identifier])
  2289. Ping a server connection. If no connection then reconnect. */
  2290. PHP_FUNCTION(mysql_ping)
  2291. {
  2292. zval *mysql_link = NULL;
  2293. int id = -1;
  2294. php_mysql_conn *mysql;
  2295. if (0 == ZEND_NUM_ARGS()) {
  2296. id = php_mysql_get_default_link(INTERNAL_FUNCTION_PARAM_PASSTHRU);
  2297. CHECK_LINK(id);
  2298. } else if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "r", &mysql_link)==FAILURE) {
  2299. return;
  2300. }
  2301. ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, &mysql_link, id, "MySQL-Link", le_link, le_plink);
  2302. PHPMY_UNBUFFERED_QUERY_CHECK();
  2303. RETURN_BOOL(! mysql_ping(mysql->conn));
  2304. }
  2305. /* }}} */
  2306. #endif
  2307. /*
  2308. * Local variables:
  2309. * tab-width: 4
  2310. * c-basic-offset: 4
  2311. * End:
  2312. * vim600: sw=4 ts=4 fdm=marker
  2313. * vim<600: sw=4 ts=4
  2314. */