DBALException bin2hex() expects parameter 1 to be string, resource given #5796

Closed
opened 2026-01-22 15:18:11 +01:00 by admin · 7 comments
Owner

Originally created by @holantomas on GitHub (Dec 5, 2017).

Originally assigned to: @Ocramius on GitHub.

Hi,
I have entity FileContent with few properities id,bytes. bytes is blob. When I'm saving file stream from upload to DB it try to throw exeption bellow but it fall on param formating when it try to call bin2hex on stream resource (uploaded file).

Trying to throw exception
SQLSTATE[08S01]: Communication link failure: 1153 Got a packet bigger than 'max_allowed_packet' bytes"

File: .../doctrine/dbal/lib/Doctrine/DBAL/DBALException.php:197

187:         *
188:         * @return string
189:         */
190:        private static function formatParameters(array $params)
191:        {
192:            return '[' . implode(', ', array_map(function ($param) {
193:                $json = @json_encode($param);
194:    
195:                if (! is_string($json) || $json == 'null' && is_string($param)) {
196:                    // JSON encoding failed, this is not a UTF-8 string.
197: // THIS LINE -->   return '"\x' . implode('\x', str_split(bin2hex($param), 2)) . '"';
198:                }
199:    
200:                return $json;
201:            }, $params)) . ']';

Don't know what else to report, so you can ask what you need.
And yes I know how to solve first exception.

Originally created by @holantomas on GitHub (Dec 5, 2017). Originally assigned to: @Ocramius on GitHub. Hi, I have entity `FileContent` with few properities `id`,`bytes`. `bytes` is `blob`. When I'm saving file stream from upload to DB it try to throw exeption bellow but it fall on param formating when it try to call bin2hex on stream resource (uploaded file). Trying to throw exception `SQLSTATE[08S01]: Communication link failure: 1153 Got a packet bigger than 'max_allowed_packet' bytes"` ``` File: .../doctrine/dbal/lib/Doctrine/DBAL/DBALException.php:197 187: * 188: * @return string 189: */ 190: private static function formatParameters(array $params) 191: { 192: return '[' . implode(', ', array_map(function ($param) { 193: $json = @json_encode($param); 194: 195: if (! is_string($json) || $json == 'null' && is_string($param)) { 196: // JSON encoding failed, this is not a UTF-8 string. 197: // THIS LINE --> return '"\x' . implode('\x', str_split(bin2hex($param), 2)) . '"'; 198: } 199: 200: return $json; 201: }, $params)) . ']'; ``` Don't know what else to report, so you can ask what you need. And yes I know how to solve first exception.
admin added the BugDuplicate labels 2026-01-22 15:18:11 +01:00
admin closed this issue 2026-01-22 15:18:12 +01:00
Author
Owner

@Ocramius commented on GitHub (Dec 5, 2017):

Could you maybe add a test case that reproduces the issue, so we can prevent regressions on a fix?

@Ocramius commented on GitHub (Dec 5, 2017): Could you maybe add a test case that reproduces the issue, so we can prevent regressions on a fix?
Author
Owner

@holantomas commented on GitHub (Dec 5, 2017):

Error is depend on your mysql settings of max_allowed_packet. By default it's set to 16M. I tried to upload PHP stream resource with 20MB file.

Database definition ofr example.

CREATE TABLE `file_content` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `bytes` longblob NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

This throws what I'm talking about. Sorry don't know if you need something better.
tmpfile() is usage just for create stream resource which cause app fall

$pdoex = new \PDOException('SQLSTATE[08S01]: Communication link failure: 1153 Got a packet bigger than \'max_allowed_packet\' bytes');
$pdoex->errorInfo = ['08S01', 1153, 'Got a packet bigger than \'max_allowed_packet\' bytes'];
$ex = new \Doctrine\DBAL\Driver\PDOException($pdoex);

\Doctrine\DBAL\DBALException::driverExceptionDuringQuery(
			new \Doctrine\DBAL\Driver\PDOMySql\Driver(),
			$ex,
			"INSERT INTO file_content (`bytes`) VALUES (?)",
			[1 => tmpfile()]);
@holantomas commented on GitHub (Dec 5, 2017): Error is depend on your mysql settings of `max_allowed_packet`. By default it's set to 16M. I tried to upload PHP stream resource with 20MB file. Database definition ofr example. ```sql CREATE TABLE `file_content` ( `id` int(11) NOT NULL AUTO_INCREMENT, `bytes` longblob NOT NULL, PRIMARY KEY (`id`) ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; ``` This throws what I'm talking about. Sorry don't know if you need something better. `tmpfile()` is usage just for create stream resource which cause app fall ```php $pdoex = new \PDOException('SQLSTATE[08S01]: Communication link failure: 1153 Got a packet bigger than \'max_allowed_packet\' bytes'); $pdoex->errorInfo = ['08S01', 1153, 'Got a packet bigger than \'max_allowed_packet\' bytes']; $ex = new \Doctrine\DBAL\Driver\PDOException($pdoex); \Doctrine\DBAL\DBALException::driverExceptionDuringQuery( new \Doctrine\DBAL\Driver\PDOMySql\Driver(), $ex, "INSERT INTO file_content (`bytes`) VALUES (?)", [1 => tmpfile()]); ```
Author
Owner

@Ocramius commented on GitHub (Dec 5, 2017):

Right, and a test case would:

  1. str_repeat('a', $db->select('SELECT setting FROM settings_table')->fetchColumn(0) * 1024 * 1024);
  2. write it to a temporary resource (php://temp)
  3. perform an insert on that table and cause an exception to be thrown

Marco Pivetta

http://twitter.com/Ocramius

http://ocramius.github.com/

On Tue, Dec 5, 2017 at 9:07 AM, Tomáš Holan notifications@github.com
wrote:

Error is depend on your mysql settings of max_allowed_packet. By default
it's set to 16M. I tried to upload PHP stream resource with 20MB file.

Database definition ofr example.

CREATE TABLE file_content (
id int(11) NOT NULL AUTO_INCREMENT,
bytes longblob NOT NULL,
PRIMARY KEY (id)
) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;

This throws what I'm talking about. Sorry don't know if you need something
better.
tmpfile() is usage just for create stream resource which cause app fall

$pdoex = new \PDOException('SQLSTATE[08S01]: Communication link failure: 1153 Got a packet bigger than 'max_allowed_packet' bytes');$pdoex->errorInfo = ['08S01', 1153, 'Got a packet bigger than 'max_allowed_packet' bytes'];$ex = new \Doctrine\DBAL\Driver\PDOException($pdoex);\Doctrine\DBAL\DBALException::driverExceptionDuringQuery( new \Doctrine\DBAL\Driver\PDOMySql\Driver(), $ex, "INSERT INTO file_content (bytes) VALUES (?)", [1 => tmpfile()]);


You are receiving this because you commented.
Reply to this email directly, view it on GitHub
https://github.com/doctrine/doctrine2/issues/6864#issuecomment-349227089,
or mute the thread
https://github.com/notifications/unsubscribe-auth/AAJakJKKJFgYKLTn3RSt3OKuQMCttRNeks5s9PnFgaJpZM4Q1x_R
.

@Ocramius commented on GitHub (Dec 5, 2017): Right, and a test case would: 1. `str_repeat('a', $db->select('SELECT setting FROM settings_table')->fetchColumn(0) * 1024 * 1024);` 2. write it to a temporary resource (`php://temp`) 3. perform an insert on that table and cause an exception to be thrown Marco Pivetta http://twitter.com/Ocramius http://ocramius.github.com/ On Tue, Dec 5, 2017 at 9:07 AM, Tomáš Holan <notifications@github.com> wrote: > Error is depend on your mysql settings of max_allowed_packet. By default > it's set to 16M. I tried to upload PHP stream resource with 20MB file. > > Database definition ofr example. > > CREATE TABLE `file_content` ( > `id` int(11) NOT NULL AUTO_INCREMENT, > `bytes` longblob NOT NULL, > PRIMARY KEY (`id`) > ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci; > > This throws what I'm talking about. Sorry don't know if you need something > better. > tmpfile() is usage just for create stream resource which cause app fall > > $pdoex = new \PDOException('SQLSTATE[08S01]: Communication link failure: 1153 Got a packet bigger than \'max_allowed_packet\' bytes');$pdoex->errorInfo = ['08S01', 1153, 'Got a packet bigger than \'max_allowed_packet\' bytes'];$ex = new \Doctrine\DBAL\Driver\PDOException($pdoex);\Doctrine\DBAL\DBALException::driverExceptionDuringQuery( new \Doctrine\DBAL\Driver\PDOMySql\Driver(), $ex, "INSERT INTO file_content (`bytes`) VALUES (?)", [1 => tmpfile()]); > > — > You are receiving this because you commented. > Reply to this email directly, view it on GitHub > <https://github.com/doctrine/doctrine2/issues/6864#issuecomment-349227089>, > or mute the thread > <https://github.com/notifications/unsubscribe-auth/AAJakJKKJFgYKLTn3RSt3OKuQMCttRNeks5s9PnFgaJpZM4Q1x_R> > . >
Author
Owner

@holantomas commented on GitHub (Dec 5, 2017):

I really don't know what you want. So I found that this issue is DBAL problem so I will close this after your answer and recreate it in right repository. But for clean I did test case commit to Doctrine/DBAL. Is'nt that better?

9f1c15815b

@holantomas commented on GitHub (Dec 5, 2017): I really don't know what you want. So I found that this issue is DBAL problem so I will close this after your answer and recreate it in right repository. But for clean I did test case commit to Doctrine/DBAL. Is'nt that better? https://github.com/doctrine/dbal/commit/9f1c15815bec44bc198ce4aabe02680e1368249d
Author
Owner

@holantomas commented on GitHub (Dec 5, 2017):

I'm ready to make PR for this commit.

Or better this can be fixed by editing Doctrine\DBAL\DBALException::formatParameters() to something like this:

private static function formatParameters(array $params)
    {
        return '[' . implode(', ', array_map(function ($param) {
            if (is_resource($param)) {
                return (string) $param;
            }

            $json = @json_encode($param);

            if (! is_string($json) || $json == 'null' && is_string($param)) {
                // JSON encoding failed, this is not a UTF-8 string.
                return '"\x' . implode('\x', str_split(bin2hex($param), 2)) . '"';
            }

            return $json;
        }, $params)) . ']';
    }
@holantomas commented on GitHub (Dec 5, 2017): I'm ready to make PR for this commit. Or better this can be fixed by editing `Doctrine\DBAL\DBALException::formatParameters()` to something like this: ```php private static function formatParameters(array $params) { return '[' . implode(', ', array_map(function ($param) { if (is_resource($param)) { return (string) $param; } $json = @json_encode($param); if (! is_string($json) || $json == 'null' && is_string($param)) { // JSON encoding failed, this is not a UTF-8 string. return '"\x' . implode('\x', str_split(bin2hex($param), 2)) . '"'; } return $json; }, $params)) . ']'; } ```
Author
Owner

@Ocramius commented on GitHub (Dec 5, 2017):

@holantomas that test looks good, but indeed it is on the DBAL project. Open a PR and we'll close this one :-)

@Ocramius commented on GitHub (Dec 5, 2017): @holantomas that test looks good, but indeed it is on the DBAL project. Open a PR and we'll close this one :-)
Author
Owner

@holantomas commented on GitHub (Dec 5, 2017):

https://github.com/doctrine/dbal/pull/2933

@holantomas commented on GitHub (Dec 5, 2017): https://github.com/doctrine/dbal/pull/2933
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: doctrine/archived-orm#5796