# [RFC] New function mysqli_quote_string

- Thread: https://externals.io/message/129653
- Original archive: https://news-web.php.net/php.internals/129653
- Started by Kamil Tekiela on 2025-12-18T21:03:22+00:00
- Messages: 13
- RFC: New function mysqli_quote_string (Implemented (PHP 8.6)) — https://externals.io/rfc/mysqli_quote_string.md
- Reply by email to internals@lists.php.net
- More for agents: search with https://externals.io/search.md?q={query} · RFCs at https://externals.io/rfc.md · JSON API at https://externals.io/api · documentation at https://externals.io/llms.txt

---

## #129653 — Kamil Tekiela — 2025-12-18T21:03:22+00:00

URL: https://externals.io/message/129653#129653

Hello,

I would like to open a discussion about adding a new function to PHP

https://wiki.php.net/rfc/mysqli_quote_string

Would you support such an addition?

Regards,
Kamil Tekiela

---

## #129657 — Matteo Beccati — 2025-12-19T13:52:17+00:00

URL: https://externals.io/message/129653#129657 · In reply to: #129653

Hi Kamil,


Il 18/12/2025 22:03, Kamil Tekiela ha scritto:
> Hello,
> 
> I would like to open a discussion about adding a new function to PHP
> 
> https://wiki.php.net/rfc/mysqli_quote_string
> 
> Would you support such an addition?

I agree with you and I prefer PDO::quote()'s behaviour over the "old" 
non-pdo quote functions.

However, I also think that manually interpolating parameters is not a 
best practice that we should encourage: query parameters are the a much 
better defence against SQL injections.

Also I'm afraid that offering two alternatives would increase the 
confusion, especially if this new function is added only to mysqli and 
not other prominent database extensions.


Cheers
-- 
Matteo

---

## #129658 — Kamil Tekiela — 2025-12-19T14:23:34+00:00

URL: https://externals.io/message/129653#129658 · In reply to: #129657

>
> Hi Kamil,
>
>
> Il 18/12/2025 22:03, Kamil Tekiela ha scritto:
> > […]
>
> I agree with you and I prefer PDO::quote()'s behaviour over the "old"
> non-pdo quote functions.
>
> However, I also think that manually interpolating parameters is not a
> best practice that we should encourage: query parameters are the a much
> better defence against SQL injections.
>
> Also I'm afraid that offering two alternatives would increase the
> confusion, especially if this new function is added only to mysqli and
> not other prominent database extensions.
>
>
> Cheers
> --
> Matteo

Hi Mateo,

The new function isn't meant to encourage this practice. My RFC
acknowledges that query parameters are the best, but unfortunately,
manual escaping is a must for certain applications.

What other extensions do you have in mind? PDO already has it, so does
PostgreSQL with pg_escape_literal(). Every extension is different and
they never have the exact same functions. In fact, what I am proposing
is to bring mysqli in line with other extensions which already have
it.

The confusion it's going to cause is minimal. The behaviour is exactly
the same as the old function, just that the quotation marks are added
automatically. It's not rocket science.

Regards,
Kamil

---

## #129659 — Hans Henrik Bergan — 2025-12-19T15:09:32+00:00

URL: https://externals.io/message/129653#129659 · In reply to: #129658

> 
> > […]
>
> Hi Mateo,
>
> The new function isn't meant to encourage this practice. My RFC
> acknowledges that query parameters are the best, but unfortunately,
> manual escaping is a must for certain applications.
>
> What other extensions do you have in mind? PDO already has it, so does
> PostgreSQL with pg_escape_literal(). Every extension is different and
> they never have the exact same functions. In fact, what I am proposing
> is to bring mysqli in line with other extensions which already have
> it.
>
> The confusion it's going to cause is minimal. The behaviour is exactly
> the same as the old function, just that the quotation marks are added
> automatically. It's not rocket science.
>
> Regards,
> Kamil
>

btw pg_escape_literal is mis-named. it does not escape - it quotes.
And there is an important difference between escaping and quoting,
at least for SQLite, it is impossible to make a binary-safe escape()
function,
but it's fully possible to make a binary-safe quote() function
(see https://github.com/php/php-src/pull/13972 )

IMO  pg_escape_literal should be renamed pg_quote_literal.

---

## #129661 — Morgan — 2025-12-19T22:38:21+00:00

URL: https://externals.io/message/129653#129661 · In reply to: #129659

> 
> 
> 
> btw pg_escape_literal is mis-named. it does not escape - it quotes.
> And there is an important difference between escaping and quoting,
> at least for SQLite, it is impossible to make a binary-safe escape() 
> function,
> but it's fully possible to make a binary-safe quote() function
> (see https://github.com/php/php-src/pull/13972 <https://github.com/php/ 
> php-src/pull/13972> )
> 
> IMO pg_escape_literal should be renamed pg_quote_literal.
 >
quote_literal() is how PostgreSQL itself names the function, and it 
would be consistent with PHP's functions being named to reflect those 
that it wraps (à la `mysqli_real_escape_string()`).

Instead, I think it got called pg_escape_string() by symmetry with 
mysql_escape_string().

---

## #129662 — Marco Pivetta — 2025-12-19T22:45:32+00:00

URL: https://externals.io/message/129653#129662 · In reply to: #129657

Hey Kamil, Matteo,

I initially looked at the mail by Kamil, and thought this was about
quoting, to which I told myself "fine, that's useful".

After reviewing the contents, plus Matteo's response, it is clear to me
that this is another attempt at escaping aimed at string interpolation.

I'd be opposed to that, even just for the fact that we're adding more tools
to a toolbox that should instead point at prepared statements.
Projects like PHPMyAdmin have vast experience in handling this sort of API,
and they should just do it themselves. BTW, it would be interesting to show
exactly (in the RFC text) why/where these projects can't use prepared
statements.

If you were to propose something about quoting (with the correct backtick
syntax, perhaps even based on the current set SQL compatibility mode), then
that could be marginally interesting.

Greets,

Marco Pivetta

https://mastodon.social/@ocramius

https://ocramius.github.io/




> Hi Kamil,
>
>
> Il 18/12/2025 22:03, Kamil Tekiela ha scritto:
> > […]
>
> I agree with you and I prefer PDO::quote()'s behaviour over the "old"
> non-pdo quote functions.
>
> However, I also think that manually interpolating parameters is not a
> best practice that we should encourage: query parameters are the a much
> better defence against SQL injections.
>
> Also I'm afraid that offering two alternatives would increase the
> confusion, especially if this new function is added only to mysqli and
> not other prominent database extensions.
>
>
> Cheers
> --
> Matteo

---

## #129663 — mickmackusa — 2025-12-19T23:28:14+00:00

URL: https://externals.io/message/129653#129663 · In reply to: #129659

> btw pg_escape_literal is mis-named. it does not escape - it quotes.
> And there is an important difference between escaping and quoting,
> at least for SQLite, it is impossible to make a binary-safe escape()
> function,
> but it's fully possible to make a binary-safe quote() function
> (see https://github.com/php/php-src/pull/13972 )
>
> IMO  pg_escape_literal should be renamed pg_quote_literal.
>

A deviation, but this triggers my naming concern with `preg_quote()`. It
doesn't quote anything, it escapes things; and it should be able to process
an array of strings! I dream of a future with a robust preg_escape() in it.

mickmackusa

---

## #129664 — Matteo Beccati — 2025-12-20T07:49:04+00:00

URL: https://externals.io/message/129653#129664 · In reply to: #129658

Hi,

Il 19/12/2025 15:23, Kamil Tekiela ha scritto:
> The new function isn't meant to encourage this practice. My RFC
> acknowledges that query parameters are the best, but unfortunately,
> manual escaping is a must for certain applications.

Such application are certainly capable of adding single quotes? I don't 
think we really need to spoon-feed them with a brand new function after 
25+ years everybody and their dog has been using real_escape_string().

> What other extensions do you have in mind? PDO already has it, so does
> PostgreSQL with pg_escape_literal(). Every extension is different and
> they never have the exact same functions. In fact, what I am proposing
> is to bring mysqli in line with other extensions which already have
> it.

Apologies, I was referring to pg_escape_string(), which I had used back 
in the days. I didn't recall pg_escape_literal + identifier: they have 
been added 14 years ago and they are using the underlying libpq 
PQEscapeLiteral and PQEscapeIdentifier functionality to offer even 
better / safer escaping.

Also ext/sqlite3 offers a non-binary safe escape function without quotes.

> The confusion it's going to cause is minimal. The behaviour is exactly
> the same as the old function, just that the quotation marks are added
> automatically. It's not rocket science.

I agree it's not rocket science to do add **single quotes**. Saying that 
we need to do that in core to avoid users "accidentally forgetting the 
quotation marks" seems a bit of an overstatement. If they had forgotten 
the quotes, most of the times the query would error out rather than 
silently working and allowing SQL-injection.

As for single quotes vs other quote flavours, I reckon it should be 
documentation material, perhaps with a big yellow box like we do for 
charsets.


Cheers
-- 
Matteo

---

## #129665 — Matteo Beccati — 2025-12-20T08:30:25+00:00

URL: https://externals.io/message/129653#129665 · In reply to: #129662

Hi Marco,

Il 19/12/2025 23:45, Marco Pivetta ha scritto:
> If you were to propose something about quoting (with the correct 
> backtick syntax, perhaps even based on the current set SQL compatibility 
> mode), then that could be marginally interesting.

If you meant quoting identifiers, I'd be all for it. In fact my New 
Year's resolution would be an RFC to add a PDO::quoteIdentifier method.


Cheers
-- 
Matteo

---

## #129684 — Craig Francis — 2025-12-24T03:26:28+00:00

URL: https://externals.io/message/129653#129684 · In reply to: #129664

> [...] Saying that we need to do that in core to avoid users "accidentally forgetting the quotation marks" seems a bit of an overstatement. If they had forgotten the quotes, most of the times the query would error out rather than silently working and allowing SQL-injection.



I wish most of the time it would error... exhibit A, found a couple of weeks ago.


$db->query('SELECT name FROM user WHERE id = ' . $db->real_escape_string($_GET['id']));


Just as an aside, Kamil, I like your proposal; while I hope that one day parameterised queries are used by everyone, we still live in a world where developers escape values themselves, and your proposal would reduce the chance of them making mistakes.

Craig

---

## #129743 — Kamil Tekiela — 2026-01-08T20:43:04+00:00

URL: https://externals.io/message/129653#129743 · In reply to: #129653

>
> Hello,
>
> I would like to open a discussion about adding a new function to PHP
>
> https://wiki.php.net/rfc/mysqli_quote_string
>
> Would you support such an addition?
>
> Regards,
> Kamil Tekiela

Hi All,

Despite receiving some criticism, I would like to bring it to a vote still.

If this method doesn't get added, then it means that this SQL
injection vulnerability will never be patched. Sure, most users have
probably switched to prepared statements and we should encourage
others to do so, but as long as manual escaping exists, it should be
reliable and not prone to hidden SQL injection.

Matteo said:
> I agree it's not rocket science to do add single quotes. Saying that
we need to do that in core to avoid users "accidentally forgetting the
quotation marks" seems a bit of an overstatement. If they had forgotten
the quotes, most of the times the query would error out rather than
silently working and allowing SQL-injection.

I don't want people to focus on the wrong part of the RFC. It's not
just about forgetting quotes. That is a problem the developer would
introduce themselves and is usually easily noticeable. The trouble is
when the user uses double quotes and thinks that everything is ok. The
main reason for this RFC is to provide SQL-injection safe function for
manual escaping of strings. The existing function leads users into a
false sense of security, as even when the data is escaped and quoted
in double quotes, it remains vulnerable to SQL injection. Putting a
warning into the PHP manual is certainly a good idea, but we could
provide a fixed function and help users even more.

It paints PHP in a bad light when we ask users to add quotation marks
manually around the return value of a function that should do it
automatically, and then we put a warning in the PHP manual saying that
while double quotes would work too, they are not SQL injection safe.
Why can't PHP just provide a function that wraps it in the correct
quotation marks instead?

Regards,
Kamil

---

## #129745 — tim@bastelstu.be — 2026-01-09T10:55:45+00:00

URL: https://externals.io/message/129653#129745 · In reply to: #129743

Hi

Am 2026-01-08 21:43, schrieb Kamil Tekiela:
> Despite receiving some criticism, I would like to bring it to a vote 
> still.
> 
> If this method doesn't get added, then it means that this SQL
> injection vulnerability will never be patched. Sure, most users have
> probably switched to prepared statements and we should encourage
> others to do so, but as long as manual escaping exists, it should be
> reliable and not prone to hidden SQL injection.

I'm in favor. It's a localized addition with a clear purpose and 
value-add, a good name and precedent in related extensions. I'm also in 
favor of using deprecations to steer users away from unsafe APIs - even 
when the functionality in question will never be removed. Unfortunately 
getting those voted in is complicated, I've had my fair share of 
experience with that in the past few PHP versions. But I agree that the 
deprecation must not happen in the same version where the replacement is 
added, since this makes incremental roll-outs of the new PHP version 
annoying since there is no version of the code base that is cleanly 
supported by both PHP versions.

With regard to the RFC itself: Please clean up the “Voting Choices” 
section, including properly filling in the vote title. The latter then 
triggers a 14 day cooldown (since changes to the voting widgets are 
Major changes): 
https://github.com/php/policies/blob/main/feature-proposals.rst#types-of-changes

Best regards
Tim Düsterhus

---

## #130084 — Kamil Tekiela — 2026-02-17T13:53:20+00:00

URL: https://externals.io/message/129653#130084 · In reply to: #129745

Hi All,

If there are no objections, I am planning to start the voting on this
RFC over the weekend.

Regards,
Kamil


>
> Hi
>
> Am 2026-01-08 21:43, schrieb Kamil Tekiela:
> > […]
>
> I'm in favor. It's a localized addition with a clear purpose and
> value-add, a good name and precedent in related extensions. I'm also in
> favor of using deprecations to steer users away from unsafe APIs - even
> when the functionality in question will never be removed. Unfortunately
> getting those voted in is complicated, I've had my fair share of
> experience with that in the past few PHP versions. But I agree that the
> deprecation must not happen in the same version where the replacement is
> added, since this makes incremental roll-outs of the new PHP version
> annoying since there is no version of the code base that is cleanly
> supported by both PHP versions.
>
> With regard to the RFC itself: Please clean up the “Voting Choices”
> section, including properly filling in the vote title. The latter then
> triggers a 14 day cooldown (since changes to the voting widgets are
> Major changes):
> https://github.com/php/policies/blob/main/feature-proposals.rst#types-of-changes
>
> Best regards
> Tim Düsterhus
