Hello,

I often host clients which have "bad" PHP/SQL code ; as for example
a "select *" + mysql_row_nums on a 200Mo table just to count lines...

So I add a little patch to throw a warning in case the result of mysql_query
is larger than a specified limit.
I use the setting "mysql.min_stored_data_before_warn" in php.ini, and the
result is :
[30-Mar-2008 04:39:56] PHP Warning: mysql_query() [<a href='function.mysql-query'>function.mysql-query</a>]: Your query use too much memory (202636 o) in /path/to/script.php on line 8

This patch seem "usefull" for me as PHP does not report the queries's memory
consumption. But maybe it should be done in mysqli and PDO extensions to ?

I'm not a "C developper", and the patch use the mysql internal struct, so
it's not really "clean". Maybe we can do it differently.

Thanks

Olivier

PS : sorry for my limited english.
diff -aur old/ext/mysql/php_mysql.c new/ext/mysql/php_mysql.c
--- old/ext/mysql/php_mysql.c	2006-08-02 12:04:11.000000000 +0200
+++ new/ext/mysql/php_mysql.c	2007-09-10 13:32:13.000000000 +0200
@@ -355,6 +355,7 @@
 	STD_PHP_INI_ENTRY("mysql.default_socket",		NULL,	PHP_INI_ALL,		OnUpdateStringUnempty,	default_socket,	zend_mysql_globals,		mysql_globals)
 	STD_PHP_INI_ENTRY("mysql.connect_timeout",		"60",	PHP_INI_ALL,		OnUpdateLong,		connect_timeout, 	zend_mysql_globals,		mysql_globals)
 	STD_PHP_INI_BOOLEAN("mysql.trace_mode",			"0",	PHP_INI_ALL,		OnUpdateLong,		trace_mode, 		zend_mysql_globals,		mysql_globals)
+	STD_PHP_INI_ENTRY("mysql.min_stored_data_before_warn",  "0",    PHP_INI_SYSTEM,         OnUpdateLong,          min_stored_data_before_warn,             zend_mysql_globals,             mysql_globals)
 PHP_INI_END()
 /* }}} */
 
@@ -1210,13 +1211,21 @@
 #endif
 #endif	/* NETWARE */
 
+
 /* {{{ php_mysql_do_query_general
  */
 static void php_mysql_do_query_general(zval **query, zval **mysql_link, int link_id, zval **db, int use_store, zval *return_value TSRMLS_DC)
 {
 	php_mysql_conn *mysql;
 	MYSQL_RES *mysql_result;
-	
+
+        MYSQL_DATA *data;
+ 	MEM_ROOT alloc;
+	USED_MEM *next;
+
+  	long result_size;
+
+
 	ZEND_FETCH_RESOURCE2(mysql, php_mysql_conn *, mysql_link, link_id, "MySQL-Link", le_link, le_plink);
 	
 	if (db) {
@@ -1283,6 +1292,24 @@
 		mysql_result=mysql_use_result(&mysql->conn);
 	} else {
 		mysql_result=mysql_store_result(&mysql->conn);
+                
+                if( mysql_result && ( MySG(min_stored_data_before_warn) > 0 ))
+                {
+			data = mysql_result->data ;                  
+  			alloc = data->alloc ;
+
+  			result_size = alloc.block_size ;
+  			for (next = alloc.used; next; next= next->next )
+  			{
+      				result_size += ( next->size - next->left );
+  			}
+
+			if( result_size >= MySG(min_stored_data_before_warn) )
+			{
+                    		php_error_docref(NULL TSRMLS_CC, E_WARNING,
+			 		"Your query use too much memory (%ld o)", result_size );
+			}
+                }
 	}
 	if (!mysql_result) {
 		if (PHP_MYSQL_VALID_RESULT(&mysql->conn)) { /* query should have returned rows */
diff -aur old/ext/mysql/php_mysql.h new/ext/mysql/php_mysql.h
--- old/ext/mysql/php_mysql.h	2006-01-01 13:50:09.000000000 +0100
+++ new/ext/mysql/php_mysql.h	2007-09-10 13:32:13.000000000 +0200
@@ -105,6 +105,7 @@
 	long connect_timeout;
 	long result_allocated;
 	long trace_mode;
+        long min_stored_data_before_warn;
 ZEND_END_MODULE_GLOBALS(mysql)
 
 #ifdef ZTS

-- 
PHP Internals - PHP Runtime Development Mailing List
To unsubscribe, visit: http://www.php.net/unsub.php

Reply via email to