You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

376 lines
11 KiB

23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
22 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
23 years ago
21 years ago
23 years ago
23 years ago
23 years ago
23 years ago
21 years ago
21 years ago
19 years ago
21 years ago
21 years ago
20 years ago
23 years ago
  1. /*
  2. +----------------------------------------------------------------------+
  3. | PHP Version 5 |
  4. +----------------------------------------------------------------------+
  5. | Copyright (c) 1997-2006 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. | Author: Georg Richter <georg@php.net> |
  16. +----------------------------------------------------------------------+
  17. $Id$
  18. */
  19. #ifdef HAVE_CONFIG_H
  20. #include "config.h"
  21. #endif
  22. #include <signal.h>
  23. #include "php.h"
  24. #include "php_ini.h"
  25. #include "ext/standard/info.h"
  26. #include "php_mysqli.h"
  27. /* {{{ proto object mysqli_connect([string hostname [,string username [,string passwd [,string dbname [,int port [,string socket]]]]]])
  28. Open a connection to a mysql server */
  29. PHP_FUNCTION(mysqli_connect)
  30. {
  31. MY_MYSQL *mysql;
  32. MYSQLI_RESOURCE *mysqli_resource;
  33. zval *object = getThis();
  34. char *hostname = NULL, *username=NULL, *passwd=NULL, *dbname=NULL, *socket=NULL;
  35. unsigned int hostname_len = 0, username_len = 0, passwd_len = 0, dbname_len = 0, socket_len = 0;
  36. long port=0;
  37. if (getThis() && !ZEND_NUM_ARGS()) {
  38. RETURN_NULL();
  39. }
  40. if (zend_parse_parameters(ZEND_NUM_ARGS() TSRMLS_CC, "|ssssls", &hostname, &hostname_len, &username, &username_len,
  41. &passwd, &passwd_len, &dbname, &dbname_len, &port, &socket, &socket_len) == FAILURE) {
  42. return;
  43. }
  44. if (!socket_len) {
  45. socket = NULL;
  46. }
  47. /* TODO: safe mode handling */
  48. if (PG(sql_safe_mode)){
  49. } else {
  50. if (!passwd) {
  51. passwd = MyG(default_pw);
  52. if (!username){
  53. username = MyG(default_user);
  54. if (!hostname) {
  55. hostname = MyG(default_host);
  56. }
  57. }
  58. }
  59. }
  60. mysql = (MY_MYSQL *) ecalloc(1, sizeof(MY_MYSQL));
  61. if (!(mysql->mysql = mysql_init(NULL))) {
  62. efree(mysql);
  63. RETURN_FALSE;
  64. }
  65. #ifdef HAVE_EMBEDDED_MYSQLI
  66. if (strcmp(hostname, ":embedded")) {
  67. unsigned int external=1;
  68. mysql_options(mysql->mysql, MYSQL_OPT_USE_REMOTE_CONNECTION, (char *)&external);
  69. } else {
  70. hostname[0] = '\0';
  71. mysql_options(mysql->mysql, MYSQL_OPT_USE_EMBEDDED_CONNECTION, 0);
  72. }
  73. #endif
  74. if (!socket) {
  75. socket = MyG(default_socket);
  76. }
  77. if (mysql_real_connect(mysql->mysql,hostname,username,passwd,dbname,port,socket,CLIENT_MULTI_RESULTS) == NULL) {
  78. /* Save error messages */
  79. php_mysqli_throw_sql_exception( mysql->mysql->net.sqlstate, mysql->mysql->net.last_errno TSRMLS_CC,
  80. "%s", mysql->mysql->net.last_error);
  81. php_mysqli_set_error(mysql_errno(mysql->mysql), (char *) mysql_error(mysql->mysql) TSRMLS_CC);
  82. /* free mysql structure */
  83. mysql_close(mysql->mysql);
  84. efree(mysql);
  85. RETURN_FALSE;
  86. }
  87. /* clear error */
  88. php_mysqli_set_error(mysql_errno(mysql->mysql), (char *) mysql_error(mysql->mysql) TSRMLS_CC);
  89. mysql->mysql->reconnect = MyG(reconnect);
  90. /* set our own local_infile handler */
  91. php_set_local_infile_handler_default(mysql);
  92. mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
  93. mysqli_resource->ptr = (void *)mysql;
  94. mysqli_resource->status = MYSQLI_STATUS_VALID;
  95. if (!object || !instanceof_function(Z_OBJCE_P(object), mysqli_link_class_entry TSRMLS_CC)) {
  96. MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_link_class_entry);
  97. } else {
  98. ((mysqli_object *) zend_object_store_get_object(object TSRMLS_CC))->ptr = mysqli_resource;
  99. }
  100. }
  101. /* }}} */
  102. /* {{{ proto int mysqli_connect_errno(void)
  103. Returns the numerical value of the error message from last connect command */
  104. PHP_FUNCTION(mysqli_connect_errno)
  105. {
  106. RETURN_LONG(MyG(error_no));
  107. }
  108. /* }}} */
  109. /* {{{ proto string mysqli_connect_error(void)
  110. Returns the text of the error message from previous MySQL operation */
  111. PHP_FUNCTION(mysqli_connect_error)
  112. {
  113. if (MyG(error_msg)) {
  114. RETURN_STRING(MyG(error_msg),1);
  115. } else {
  116. RETURN_NULL();
  117. }
  118. }
  119. /* }}} */
  120. /* {{{ proto mixed mysqli_fetch_array (object result [,int resulttype])
  121. Fetch a result row as an associative array, a numeric array, or both */
  122. PHP_FUNCTION(mysqli_fetch_array)
  123. {
  124. php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, 0, 0);
  125. }
  126. /* }}} */
  127. /* {{{ proto mixed mysqli_fetch_assoc (object result)
  128. Fetch a result row as an associative array */
  129. PHP_FUNCTION(mysqli_fetch_assoc)
  130. {
  131. php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQLI_ASSOC, 0);
  132. }
  133. /* }}} */
  134. /* {{{ proto mixed mysqli_fetch_object (object result [, string class_name [, NULL|array ctor_params]])
  135. Fetch a result row as an object */
  136. PHP_FUNCTION(mysqli_fetch_object)
  137. {
  138. php_mysqli_fetch_into_hash(INTERNAL_FUNCTION_PARAM_PASSTHRU, MYSQLI_ASSOC, 1);
  139. }
  140. /* }}} */
  141. /* {{{ proto bool mysqli_multi_query(object link, string query)
  142. Binary-safe version of mysql_query() */
  143. PHP_FUNCTION(mysqli_multi_query)
  144. {
  145. MY_MYSQL *mysql;
  146. zval *mysql_link;
  147. char *query = NULL;
  148. unsigned int query_len;
  149. if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &mysql_link, mysqli_link_class_entry, &query, &query_len) == FAILURE) {
  150. return;
  151. }
  152. MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL *, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID);
  153. MYSQLI_ENABLE_MQ;
  154. if (mysql_real_query(mysql->mysql, query, query_len)) {
  155. char s_error[MYSQL_ERRMSG_SIZE], s_sqlstate[SQLSTATE_LENGTH+1];
  156. unsigned int s_errno;
  157. MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
  158. /* we have to save error information, cause
  159. MYSQLI_DISABLE_MQ will reset error information */
  160. strcpy(s_error, mysql_error(mysql->mysql));
  161. strcpy(s_sqlstate, mysql_sqlstate(mysql->mysql));
  162. s_errno = mysql_errno(mysql->mysql);
  163. MYSQLI_DISABLE_MQ;
  164. /* restore error information */
  165. strcpy(mysql->mysql->net.last_error, s_error);
  166. strcpy(mysql->mysql->net.sqlstate, s_sqlstate);
  167. mysql->mysql->net.last_errno = s_errno;
  168. RETURN_FALSE;
  169. }
  170. RETURN_TRUE;
  171. }
  172. /* }}} */
  173. /* {{{ proto mixed mysqli_query(object link, string query [,int resultmode]) */
  174. PHP_FUNCTION(mysqli_query)
  175. {
  176. MY_MYSQL *mysql;
  177. zval *mysql_link;
  178. MYSQLI_RESOURCE *mysqli_resource;
  179. MYSQL_RES *result;
  180. char *query = NULL;
  181. unsigned int query_len;
  182. unsigned long resultmode = MYSQLI_STORE_RESULT;
  183. if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os|l", &mysql_link, mysqli_link_class_entry, &query, &query_len, &resultmode) == FAILURE) {
  184. return;
  185. }
  186. if (!query_len) {
  187. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Empty query");
  188. RETURN_FALSE;
  189. }
  190. if (resultmode != MYSQLI_USE_RESULT && resultmode != MYSQLI_STORE_RESULT) {
  191. php_error_docref(NULL TSRMLS_CC, E_WARNING, "Invalid value for resultmode");
  192. RETURN_FALSE;
  193. }
  194. MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL*, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID);
  195. MYSQLI_DISABLE_MQ;
  196. if (mysql_real_query(mysql->mysql, query, query_len)) {
  197. MYSQLI_REPORT_MYSQL_ERROR(mysql->mysql);
  198. RETURN_FALSE;
  199. }
  200. if (!mysql_field_count(mysql->mysql)) {
  201. /* no result set - not a SELECT */
  202. if (MyG(report_mode) & MYSQLI_REPORT_INDEX) {
  203. php_mysqli_report_index(query, mysql->mysql->server_status TSRMLS_CC);
  204. }
  205. RETURN_TRUE;
  206. }
  207. result = (resultmode == MYSQLI_USE_RESULT) ? mysql_use_result(mysql->mysql) : mysql_store_result(mysql->mysql);
  208. if (!result) {
  209. php_mysqli_throw_sql_exception(mysql->mysql->net.sqlstate, mysql->mysql->net.last_errno TSRMLS_CC,
  210. "%s", mysql->mysql->net.last_error);
  211. RETURN_FALSE;
  212. }
  213. if (MyG(report_mode) & MYSQLI_REPORT_INDEX) {
  214. php_mysqli_report_index(query, mysql->mysql->server_status TSRMLS_CC);
  215. }
  216. mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
  217. mysqli_resource->ptr = (void *)result;
  218. mysqli_resource->status = MYSQLI_STATUS_VALID;
  219. MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_result_class_entry);
  220. }
  221. /* }}} */
  222. /* {{{ proto object mysqli_get_warnings(object link) */
  223. PHP_FUNCTION(mysqli_get_warnings)
  224. {
  225. MY_MYSQL *mysql;
  226. zval *mysql_link;
  227. MYSQLI_RESOURCE *mysqli_resource;
  228. MYSQLI_WARNING *w;
  229. if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
  230. return;
  231. }
  232. MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL*, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID);
  233. if (mysql_warning_count(mysql->mysql)) {
  234. w = php_get_warnings(mysql->mysql);
  235. } else {
  236. RETURN_FALSE;
  237. }
  238. mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
  239. mysqli_resource->ptr = mysqli_resource->info = (void *)w;
  240. MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_warning_class_entry);
  241. }
  242. /* }}} */
  243. /* {{{ proto object mysqli_stmt_get_warnings(object link) */
  244. PHP_FUNCTION(mysqli_stmt_get_warnings)
  245. {
  246. MY_STMT *stmt;
  247. zval *stmt_link;
  248. MYSQLI_RESOURCE *mysqli_resource;
  249. MYSQLI_WARNING *w;
  250. if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &stmt_link, mysqli_stmt_class_entry) == FAILURE) {
  251. return;
  252. }
  253. MYSQLI_FETCH_RESOURCE(stmt, MY_STMT*, &stmt_link, "mysqli_stmt", 1);
  254. if (mysql_warning_count(stmt->stmt->mysql)) {
  255. w = php_get_warnings(stmt->stmt->mysql);
  256. } else {
  257. RETURN_FALSE;
  258. }
  259. mysqli_resource = (MYSQLI_RESOURCE *)ecalloc (1, sizeof(MYSQLI_RESOURCE));
  260. mysqli_resource->ptr = mysqli_resource->info = (void *)w;
  261. MYSQLI_RETURN_RESOURCE(mysqli_resource, mysqli_warning_class_entry);
  262. }
  263. /* }}} */
  264. #ifdef HAVE_MYSQLI_SET_CHARSET
  265. /* {{{ proto bool mysqli_set_charset(object link, string csname)
  266. sets client character set */
  267. PHP_FUNCTION(mysqli_set_charset)
  268. {
  269. MY_MYSQL *mysql;
  270. zval *mysql_link;
  271. char *cs_name = NULL;
  272. unsigned int len;
  273. if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "Os", &mysql_link, mysqli_link_class_entry, &cs_name, &len) == FAILURE) {
  274. return;
  275. }
  276. MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL*, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID);
  277. if (mysql_set_character_set(mysql->mysql, cs_name)) {
  278. RETURN_FALSE;
  279. }
  280. RETURN_TRUE;
  281. }
  282. /* }}} */
  283. #endif
  284. #ifdef HAVE_MYSQLI_GET_CHARSET
  285. /* {{{ proto object mysqli_get_charset(object link)
  286. returns a character set object */
  287. PHP_FUNCTION(mysqli_get_charset)
  288. {
  289. MY_MYSQL *mysql;
  290. zval *mysql_link;
  291. MY_CHARSET_INFO cs;
  292. if (zend_parse_method_parameters(ZEND_NUM_ARGS() TSRMLS_CC, getThis(), "O", &mysql_link, mysqli_link_class_entry) == FAILURE) {
  293. return;
  294. }
  295. MYSQLI_FETCH_RESOURCE(mysql, MY_MYSQL*, &mysql_link, "mysqli_link", MYSQLI_STATUS_VALID);
  296. object_init(return_value);
  297. mysql_get_character_set_info(mysql->mysql, &cs);
  298. add_property_string(return_value, "charset", (cs.name) ? (char *)cs.csname : "", 1);
  299. add_property_string(return_value, "collation",(cs.name) ? (char *)cs.name : "", 1);
  300. add_property_string(return_value, "comment", (cs.comment) ? (char *)cs.comment : "", 1);
  301. add_property_string(return_value, "dir", (cs.dir) ? (char *)cs.dir : "", 1);
  302. add_property_long(return_value, "min_length", cs.mbminlen);
  303. add_property_long(return_value, "max_length", cs.mbmaxlen);
  304. add_property_long(return_value, "number", cs.number);
  305. add_property_long(return_value, "state", cs.state);
  306. }
  307. /* }}} */
  308. #endif
  309. /*
  310. * Local variables:
  311. * tab-width: 4
  312. * c-basic-offset: 4
  313. * End:
  314. * vim600: noet sw=4 ts=4 fdm=marker
  315. * vim<600: noet sw=4 ts=4
  316. */