mysql_insert_id() stopped working after PHP update - php

I am preparing to update a live web server from PHP 5.2.12 to 5.3.5. In preparation, I have performed the update on a second server which is a mirror of the live one ("dev" server). Both servers are using FreeBSD, and both used ports to install PHP and MySQL. The live server is using MySQL 5.0.89, the newly upgraded dev server is using 5.1.54.
The following code executes as expected on the live server (PHP 5.2.12/5.0.89), returning the value of the AUTO_INCREMENT row that was just inserted. This function is part of a database class that is used throughout the site, where "$this->_private['cn']" is the resource link.
public function insert ($sql=false) {
#mysql_select_db($this->_private['db_name'], $this->_private['cn']);
$res = null;
if (false !== $sql) {
$query_obj = mysql_query($sql, $this->_private['cn']);
if ($query_obj)
$res = mysql_insert_id($this->_private['cn']);
}
return $res;
}
On the dev server (5.3.5/5.1.54), the return is zero. Note - not null (which is returned if the query fails), but ZERO. I can look at the table and verify that a new row has in fact been inserted, and the auto increment field has properly advanced. The field value is currently at 121288, so it is well within PHP's integer range. I've even re-created the class's code on a simple page and get the same result. mysql_error() indicates no failures. Error reporting is set to E_ALL, not a peep there.
ARGH! Any ideas?

see this bug which recommends following your query with SELECT LAST_INSERT_ID()

Related

mysqli_commit fails when select statement is added

Problem:
Unable to store data with mySQL stored procedure with mysqli_begin_transaction.
Details:
The below code will do simple insert and select using mysql stored procedure. Code runs fine without select statement. However once the select statement is added, it won't commit any data even the query returns success at PHP side.
Snippets (PHP):
$DB_DRRM_SQLI = mysqli_connect("localhost","root","", "sandbox_db");
mysqli_begin_transaction($DB_DRRM_SQLI);
$SQL_QUERY_CODE = "CALL SANDBOX_TEST()";
$DB_QUERY = mysqli_query($DB_DRRM_SQLI, $SQL_QUERY_CODE);
// ERROR REPORTING
if($DB_QUERY === false)
{
echo mysqli_error($DB_DRRM_SQLI);
mysqli_rollback($DB_DRRM_SQLI);
}
else
{
echo 'success';
mysqli_commit($DB_DRRM_SQLI);
}
exit;
Snippets (mySQL Stored procedure):
BEGIN
INSERT INTO
`sandbox_table`
(
`SOME_STRING`
)
VALUES
(
'ABCDEFGHIJKL...'
);
SELECT
LAST_INSERT_ID() AS INSERTED_ID,
'ABCDE...' AS OTHER_PARAMS;
END
Database (Table sandbox_table):
RECORD_PRIMARY_ID (Int - Auto increment)
SOME_STRING (Varchar - 500 length)
Spec:
PHP version: 5.6.14
10.1.8-MariaDB
Storage Engine: InnoDB
Notes:
If transaction is made at stored procedure works fine, but I need a PHP managed transaction to handle multiple query requests and response depending on the result of query.
(It can be a possible last resort if there's no other solution, where I need to convert whole PHP code to stored procedure and need pass tons of parameter)
Methods Tested:
Tried with other PHP version 7.0.9 with same result (10.1.16-MariaDB)
Tested with new database with no other data except sandbox_tableand above stored procedure.
Tested without additional include libraries (tested with purely on above snippets).
Solution:
It was caused by Commands out of sync error at mysqli_commit. Seems the mysqli won't allow committing transaction while the query is open, which happens if you add select statement to above stored procedure.
So to handle this, it must close the query first or put the query to buffer.
Snippets (PHP):
// SQL Database
$DB_DRRM_SQLI = mysqli_connect("localhost","root","", "sandbox_db");
mysqli_begin_transaction($DB_DRRM_SQLI);
$SQL_QUERY_CODE = "CALL SANDBOX_TEST()";
$DB_QUERY = mysqli_query($DB_DRRM_SQLI, $SQL_QUERY_CODE);
// ERROR REPORTING
if($DB_QUERY === false)
{
echo mysqli_error($DB_DRRM_SQLI);
mysqli_rollback($DB_DRRM_SQLI);
}
else
{
// Must free current query result before committing transaction
#mysqli_free_result($DB_QUERY);
#mysqli_next_result($DB_DRRM_SQLI);
if(mysqli_commit($DB_DRRM_SQLI) === false)
{
echo mysqli_error($DB_DRRM_SQLI);
}
else
{
echo 'success';
}
}
exit;

$msqli->insert_id always returns '0' after a server move

Until a server move this week (by the hosting provider) this code worked perfectly:
$conn = new mysqli('localhost','dbuser','dbpass','dbname');
$conn->set_charset("utf8");
$new_tester = $conn->prepare("INSERT INTO testers (tid,first_name,last_name,t_email,company,last_login,ip_address) VALUES (NULL,?,?,?,?,NULL,?)");
$new_tester->bind_param('sssss',$first_name,$last_name,$t_email,$up_company,$ip_address);
$new_tester->execute();
$userid = $conn->insert_id;
$new_tester->store_result();
$new_tester->close();
print($userid);
Since the move, insert_id always returns 0. I've moved the line with insert_id before/after store_result() and close(), and it still doesn't work.
For the record, it works as expected on my local machine. Both my machine and the server use PHP 5.6 and MySQL 5.0.11. AUTO_INCREMENT is in use.

Php adodb CacheExecute com_exception arguments wrong type

I'm trying to get ADODB caching to work. I have a php script where i define the DB connection.
global $conn;
$conn = new COM ("ADODB.Connection");
$connStr = "PROVIDER-SQLOLEDB;SERVER=;UID=;PWD=;DATABASE=);
$conn->open($connStr);
I left the unnecessary details out of the picture.
Then in some other script i import the connection.php, and then try to make a normal query.
$query = "SELECT * from table where some_id = 21540 and other_id = BOGUS_INFO"
$rs = $GLOBALS['conn']->CacheExecute(60,$query);
This returns Uncaught exception 'com_exception'.. ADODB.Connection Arguments are of the wrong type,are out of acceptable range, or are in conflict with another.
I'm baffled because the next line of code works flawlessly.
$rs = $GLOBALS['conn']->execute($query); //OK!
Any ideeas?
I also tried CacheGetOne but i get the same error.
Could it be from the way i defined this thing below? (it's literally like that in my code)
$GLOBALS['ADODB_CACHE_DIR']=$_SERVER['DOCUMENT_ROOT'].'/../cache/adodb';
Well after alot of hassle, i kinda found an answer by choosing another way of doing things. I downloaded the latest ADODB build. Inserted it in my project, and modified files accordingly:
The connection.php changed to:
require('PATH/adodb.inc.php');
require('PATH/adodb-csvlib.inc.php');//read somewhere that i need this for the caching executes
$GLOBALS['ADODB_CACHE_DIR'] = $_SERVER['DOCUMENT_ROOT'].'/cache/adodb';
global $ADODB_CACHE_DIR; //don't know which one adodb usese really to identify cache directory so for safety - both
$ADODB_CACHE_DIR = $_SERVER['DOCUMENT_ROOT'].'/cache/adodb';
$conn = NewADOConnection('mssqlnative');//i tried first with mssql simple but script terminated execution on execute() attempt.. no error.. no nothing.. no output .. strange
$conn->Connect($myServer, $myUser, $myPass, $myDb);
After that i had to fiddle a bit with the code because,
$rs = $conn->CacheExecute(time,query)
returns Adodbrecordset_array_mssqlnative Object, and not an array, and, in my code i used to display and manipulate values as
while (!$rs->EOF) {
$rs['row']->value;
$rs->MoveNext();
}
and now they should be
$rs->fields['row'];
Another tricky thing was getting the fields array to be associated to the names of the columns in my query, but after a short search i discovered
$GLOBALS['conn']->SetFetchMode(ADODB_FETCH_ASSOC);
and voila! Everything works, even the caching.
It took script execution times with this bare optimisation from 1 sec to 0.1 or even 0.005 sometimes.

PHP/MSSQL/SQL Profiler: not executing incoming SQL

I have a very simple INSERT statement that I can run using SSMS. When I run the same INSERT statement using PHP mssql_execute or mssql_query SQL profiler shows me that the 'TextData' is identical when sent in by PHP as it is when sent in by SSMS. The problem is when executed via the PHP code, the INSERT never actually happens, whereas when run from within SSMS, it inserts just fine. Any ideas?
MS SQL: 2008 R2
PHP: 5.4, freetds 8.0
PHP error:
PHP Warning: mssql_execute(): message: Internal Query Processor Error: The query processor could not produce a query plan. For more information, contact Customer Support Services. (severity 16) in /home/...
Edit: PHP relevant PHP added
<?php
putenv('FREETDS=/home/###/freetds.conf');
putenv('FREETDSCONF=/home/###/freetds.conf');
$link = mssql_connect('mssqlserver', '###','###'); // connect
if ( !$link ) {
if ( function_exists('error_get_last') ) {
var_dump(error_get_last());
}
die('connection failed');
}
// Create a new statement
$stmt = mssql_init('Db.dbo.SprocName');
// Some values
$a = 1;
$b = 'test';
$c = 'myname';
// Bind values
mssql_bind($stmt,'#a',$a,SQLINT2,false,false);
mssql_bind($stmt,'#b',$b,SQLVARCHAR,false,false,8000);
mssql_bind($stmt,'#c',$c,SQLVARCHAR,false,false,50);
// Execute the statement
mssql_execute($stmt);
// And we can free it like so:
mssql_free_statement($stmt);
?>
The stored procedure (Db.dbo.SprocName) did a simple insert on a table, lets call it (Db.dbo.TableName). When I removed the foreign key from Db.dbo.TableName then the PHP mssql INSERT calls started working.
I realize this technically resolves the issue, but in practice its not acceptable. Those FK's are there for a reason :). Any thoughts?

Database connection problems in PHP/MySQL

When I run the script below with the added line,
$count = 1;
I get a value of 1 on the screen, but when I take that line out I don't get get anything at all. tried moving it above the $count=mysql_num_rows($result); and I still didn't get a value.
$sql="SELECT EMAIL FROM CUSTOMER WHERE email='$myemail' and password='$mypassword'";
$result=mysql_query($sql);
$count=mysql_num_rows($result);
$count = 1;
echo $count;
What am I doing wrong here? I have never used PHP until now. The error is:
Can't connect to local MySQL server through socket
'/var/run/mysqld/mysqld.sock' (2)
This means that your MySQL server socket (/var/run/mysqld/mysqld.sock) is either missing or corrupt.
It could also mean that MySQL service is not working right, try restarting in SSH using:
$ service mysqld restart
If it says the service is missing, then say:
$ service mysql restart
I would guess at an a error with your SQL query (var_dump($count); would return false in this case).
To check this, I would do 2 things:
After your query do if(!$result) echo mysql_error( ); - this will show you any errors that happen while talking to the database
To check your SQL is being formed correctly, create it in a variable (e.g. $sql = "SELECT email ...";) and echo it out.
EDIT: Ahh just seen the update - it's a connection issue. Check that your mysql_connect( ) has the right host, username & password. Otherwise it could be a problem on your system (e.g. firewall or similar)
EDIT 2: As has been rightly pointed out, mysql_connect details would cause a different connection error to the one you're seeing. I've had a quick Google for it, and this cropped up http://lists.mysql.com/mysql/204035. Not sure it'll be any use as I've not read it through, but it does describe some steps for the solving this problem on someone else's system.
When you can't connect successfully to the database, return value from mysql_query function ($result) would not be a valid value. so when you give it to mysql_num_rows function, it fails & returns FALSE value, which has no visual effect on output screen!

Categories