-
Notifications
You must be signed in to change notification settings - Fork 7.9k
Mysqli bind in execute #6271
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
kamil-tekiela
merged 17 commits into
php:master
from
kamil-tekiela:mysqli-bind-in-execute
Apr 14, 2021
Merged
Mysqli bind in execute #6271
Changes from all commits
Commits
Show all changes
17 commits
Select commit
Hold shift + click to select a range
38bc9fb
Mysqli: bind-in-execute (mysqlnd)
kamil-tekiela 4322222
Provided test case for bind-in-execute
kamil-tekiela 734d63b
Fix arginfo and test case
kamil-tekiela b13e6aa
make the parameter properly nullable
kamil-tekiela a88eb11
Fix test case and add 12th check for too many params
kamil-tekiela 54eb6e5
Add a hard exception if more values provided than parameters
kamil-tekiela 256c76b
Make errors consisent with ValueError
kamil-tekiela 17a1611
Apply code formatting from code review
kamil-tekiela ad50dd6
Change zval to a HashTable
kamil-tekiela 5fc50fe
Add error for libmysqlclient
kamil-tekiela 28d21cb
Only allow list arrays
kamil-tekiela 7f86665
Make $params non-nullable
kamil-tekiela ada609d
Add zend_assert
kamil-tekiela 1ccc141
Clean up test case and reindent
kamil-tekiela dd4fdf6
Revert "Make $params non-nullable"
kamil-tekiela 46257dc
Update UPGRADING
kamil-tekiela 146e8c9
Clean up test case and unindent
kamil-tekiela File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,146 @@ | ||
--TEST-- | ||
mysqli_stmt_execute() - bind in execute | ||
--SKIPIF-- | ||
<?php | ||
require_once 'skipif.inc'; | ||
require_once 'skipifconnectfailure.inc'; | ||
if (!stristr(mysqli_get_client_info(), 'mysqlnd')) { | ||
die("skip: only available in mysqlnd"); | ||
} | ||
?> | ||
--FILE-- | ||
<?php | ||
require_once "connect.inc"; | ||
|
||
require 'table.inc'; | ||
|
||
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); | ||
|
||
// first, control case | ||
$id = 1; | ||
$abc = 'abc'; | ||
$stmt = $link->prepare('SELECT label, ? AS anon, ? AS num FROM test WHERE id=?'); | ||
$stmt->bind_param('sss', ...[&$abc, 42, $id]); | ||
$stmt->execute(); | ||
assert($stmt->get_result()->fetch_assoc() === ['label'=>'a', 'anon'=>'abc', 'num' => '42']); | ||
$stmt = null; | ||
|
||
// 1. same as the control case, but skipping the middle-man (bind_param) | ||
$stmt = $link->prepare('SELECT label, ? AS anon, ? AS num FROM test WHERE id=?'); | ||
$stmt->execute([&$abc, 42, $id]); | ||
assert($stmt->get_result()->fetch_assoc() === ['label'=>'a', 'anon'=>'abc', 'num' => '42']); | ||
$stmt = null; | ||
|
||
// 2. param number has to match - missing 1 parameter | ||
$stmt = $link->prepare('SELECT label, ? AS anon, ? AS num FROM test WHERE id=?'); | ||
try { | ||
$stmt->execute([&$abc, 42]); | ||
} catch (ValueError $e) { | ||
echo '[001] '.$e->getMessage()."\n"; | ||
} | ||
$stmt = null; | ||
|
||
// 3. Too many parameters | ||
$stmt = $link->prepare('SELECT label, ? AS anon, ? AS num FROM test WHERE id=?'); | ||
try { | ||
$stmt->execute([&$abc, null, $id, 24]); | ||
} catch (ValueError $e) { | ||
echo '[002] '.$e->getMessage()."\n"; | ||
} | ||
$stmt = null; | ||
|
||
// 4. param number has to match - missing all parameters | ||
$stmt = $link->prepare('SELECT label, ? AS anon, ? AS num FROM test WHERE id=?'); | ||
try { | ||
$stmt->execute([]); | ||
} catch (ValueError $e) { | ||
echo '[003] '.$e->getMessage()."\n"; | ||
} | ||
$stmt = null; | ||
|
||
// 5. param number has to match - missing argument to execute() | ||
$stmt = $link->prepare('SELECT label, ? AS anon, ? AS num FROM test WHERE id=?'); | ||
try { | ||
$stmt->execute(); | ||
} catch (mysqli_sql_exception $e) { | ||
echo '[004] '.$e->getMessage()."\n"; | ||
} | ||
$stmt = null; | ||
|
||
// 6. wrong argument to execute() | ||
$stmt = $link->prepare('SELECT label, ? AS anon, ? AS num FROM test WHERE id=?'); | ||
try { | ||
$stmt->execute(42); | ||
} catch (TypeError $e) { | ||
echo '[005] '.$e->getMessage()."\n"; | ||
} | ||
$stmt = null; | ||
|
||
// 7. objects are not arrays and are not accepted | ||
$stmt = $link->prepare('SELECT label, ? AS anon, ? AS num FROM test WHERE id=?'); | ||
try { | ||
$stmt->execute((object)[&$abc, 42, $id]); | ||
} catch (TypeError $e) { | ||
echo '[006] '.$e->getMessage()."\n"; | ||
} | ||
$stmt = null; | ||
|
||
// 8. arrays by reference work too | ||
$stmt = $link->prepare('SELECT label, ? AS anon, ? AS num FROM test WHERE id=?'); | ||
$arr = [&$abc, 42, $id]; | ||
$arr2 = &$arr; | ||
$stmt->execute($arr2); | ||
assert($stmt->get_result()->fetch_assoc() === ['label'=>'a', 'anon'=>'abc', 'num' => '42']); | ||
$stmt = null; | ||
|
||
// 9. no placeholders in statement. nothing to bind in an empty array | ||
$stmt = $link->prepare('SELECT label FROM test WHERE id=1'); | ||
$stmt->execute([]); | ||
assert($stmt->get_result()->fetch_assoc() === ['label'=>'a']); | ||
$stmt = null; | ||
|
||
// 10. once bound the values are persisted. Just like in PDO | ||
$stmt = $link->prepare('SELECT label, ? AS anon, ? AS num FROM test WHERE id=?'); | ||
$stmt->execute(['abc', 42, $id]); | ||
assert($stmt->get_result()->fetch_assoc() === ['label'=>'a', 'anon'=>'abc', 'num' => '42']); | ||
$stmt->execute(); // no argument here. Values are already bound | ||
assert($stmt->get_result()->fetch_assoc() === ['label'=>'a', 'anon'=>'abc', 'num' => '42']); | ||
try { | ||
$stmt->execute([]); // no params here. PDO doesn't throw an error, but mysqli does | ||
} catch (ValueError $e) { | ||
echo '[007] '.$e->getMessage()."\n"; | ||
} | ||
$stmt = null; | ||
|
||
// 11. mixing binding styles not possible. Also, NULL should stay NULL when bound as string | ||
$stmt = $link->prepare('SELECT label, ? AS anon, ? AS num FROM test WHERE id=?'); | ||
$stmt->bind_param('sss', ...['abc', 42, null]); | ||
$stmt->execute([null, null, $id]); | ||
assert($stmt->get_result()->fetch_assoc() === ['label'=>'a', 'anon'=>null, 'num' => null]); | ||
$stmt = null; | ||
|
||
// 12. Only list arrays are allowed | ||
$stmt = $link->prepare('SELECT label, ? AS anon, ? AS num FROM test WHERE id=?'); | ||
try { | ||
$stmt->execute(['A'=>'abc', 2=>42, null=>$id]); | ||
} catch (ValueError $e) { | ||
echo '[008] '.$e->getMessage()."\n"; | ||
} | ||
$stmt = null; | ||
|
||
|
||
mysqli_close($link); | ||
?> | ||
--CLEAN-- | ||
<?php | ||
require_once "clean_table.inc"; | ||
?> | ||
--EXPECT-- | ||
[001] mysqli_stmt::execute(): Argument #1 ($params) must consist of exactly 3 elements, 2 present | ||
[002] mysqli_stmt::execute(): Argument #1 ($params) must consist of exactly 3 elements, 4 present | ||
[003] mysqli_stmt::execute(): Argument #1 ($params) must consist of exactly 3 elements, 0 present | ||
[004] No data supplied for parameters in prepared statement | ||
[005] mysqli_stmt::execute(): Argument #1 ($params) must be of type ?array, int given | ||
[006] mysqli_stmt::execute(): Argument #1 ($params) must be of type ?array, stdClass given | ||
[007] mysqli_stmt::execute(): Argument #1 ($params) must consist of exactly 3 elements, 0 present | ||
[008] mysqli_stmt::execute(): Argument #1 ($params) must be a list array |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,44 @@ | ||
--TEST-- | ||
mysqli_stmt_execute() - bind in execute - not supported with libmysql | ||
--SKIPIF-- | ||
<?php | ||
require_once 'skipif.inc'; | ||
require_once 'skipifconnectfailure.inc'; | ||
if (stristr(mysqli_get_client_info(), 'mysqlnd')) { | ||
die("skip: only applicable for libmysqlclient"); | ||
} | ||
?> | ||
--FILE-- | ||
<?php | ||
require_once "connect.inc"; | ||
|
||
require 'table.inc'; | ||
|
||
mysqli_report(MYSQLI_REPORT_ERROR | MYSQLI_REPORT_STRICT); | ||
|
||
// first, control case | ||
$id = 1; | ||
$abc = 'abc'; | ||
$stmt = $link->prepare('SELECT label, ? AS anon, ? AS num FROM test WHERE id=?'); | ||
$stmt->bind_param('sss', ...[&$abc, 42, $id]); | ||
$stmt->execute(); | ||
assert($stmt->get_result()->fetch_assoc() === ['label'=>'a', 'anon'=>'abc', 'num' => '42']); | ||
$stmt = null; | ||
|
||
// 1. same as the control case, but skipping the middle-man (bind_param) | ||
$stmt = $link->prepare('SELECT label, ? AS anon, ? AS num FROM test WHERE id=?'); | ||
try { | ||
$stmt->execute([&$abc, 42, $id]); | ||
} catch (ArgumentCountError $e) { | ||
echo '[001] '.$e->getMessage()."\n"; | ||
} | ||
$stmt = null; | ||
|
||
mysqli_close($link); | ||
?> | ||
--CLEAN-- | ||
<?php | ||
require_once "clean_table.inc"; | ||
?> | ||
--EXPECT-- | ||
[001] Binding parameters in execute is not supported with libmysqlclient |
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.