ます’s Blog - どうでもいい記事100選

どうでもいい記事100選

mysql_insert_id関数

mysql_insert_id( )は、元のMySQL C API関数 mysql_insert_id( )の返り値の型をlong型に変換します。
AUTO_INCREMENT カラムがBIGINTのカラム型を有している場合、mysql_insert_id( )で返される型は不正確になります。

代わりに、MySQL SQL内部関数 LAST_INSERT_ID()を使用してください。

との事で前から使いづらいと思っていました。という訳で実験的にパッチを作ってみた。
ていうかDBD-mysqlやってた事をパクっただけなんだけどな。

--- php-4.3.11,orig/ext/mysql/php_mysql.c	Wed Feb 23 00:00:49 2005
+++ php-4.3.11/ext/mysql/php_mysql.c	Fri Jun 24 19:46:33 2005
@@ -57,6 +57,8 @@
 #include "php_ini.h"
 #include "php_mysql.h"
 
+static char *_php_my_ulonglong2string( my_ulonglong bigint_buffer );
+
 /* True globals, no need for thread safety */
 static int le_result, le_link, le_plink;
 
@@ -1709,12 +1711,13 @@
 }
 /* }}} */
 
-/* {{{ proto int mysql_insert_id([int link_identifier])
+/* {{{ proto mixed mysql_insert_id([int link_identifier])
    Gets the ID generated from the previous INSERT operation */
 PHP_FUNCTION(mysql_insert_id)
 {
 	zval **mysql_link;
 	int id;
+	int flg = 0;
 	php_mysql_conn *mysql;
 	
 	switch(ZEND_NUM_ARGS()) {
@@ -1728,6 +1731,13 @@
 			}
 			id = -1;
 			break;
+		case 2:
+			if (zend_get_parameters_ex(1, &mysql_link)==FAILURE) {
+				RETURN_FALSE;
+			}
+			id = -1;
+			flg = 1;
+			break;
 		default:
 			WRONG_PARAM_COUNT;
 			break;
@@ -1735,12 +1745,37 @@
 	
 	ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, mysql_link, id, "MySQL-Link", le_link, le_plink);
 	
+	if( flg == 1 ){
+		char *bigint_field = NULL;
+		bigint_field = _php_my_ulonglong2string( (my_ulonglong)mysql_insert_id( &mysql->conn ) );
+		Z_STRLEN_P(return_value) = strlen( bigint_field );
+		Z_STRVAL_P(return_value) = bigint_field;
+		Z_TYPE_P(return_value)   = IS_STRING;
+	} else{
 	/* conversion from int64 to long happing here */
 	Z_LVAL_P(return_value) = (long) mysql_insert_id(&mysql->conn);
 	Z_TYPE_P(return_value) = IS_LONG;
+	}
 }
 /* }}} */
 
+static char *_php_my_ulonglong2string( my_ulonglong bigint_buffer )
+{
+ char buffer[64];
+ char *ptr = buffer+63;
+ *ptr = '\0';
+ char zero_buffer[] = "0";
+
+ if( bigint_buffer <= 0 ){ return estrndup( zero_buffer, 2 ); }
+
+ while( bigint_buffer > 0 )
+ {
+  *(--ptr) = ('0' + (bigint_buffer % 10));
+  bigint_buffer = bigint_buffer / 10;
+ }
+
+ return estrndup( ptr, ( buffer + 63 ) - ptr );
+}
 
 /* {{{ proto mixed mysql_result(resource result, int row [, mixed field])
    Gets result data */

# 補足
Solaris8(sparc)だと

+ *ptr = '\0';

があると駄目らしい。。。シンタックス・エラーになるんだけどLinuxの方ではOKだった。
GCCのバージョンによるのかな。ていうかDBD-mysqlでパクってるトコロなんだけど。