MigxDb (long)blob fields contain "0" in stead of filecontents


I have copied a working ModX site to a testserver with XAmpp (Php 7.3) and MariaDb.
I upgraded it to 2.7.2.pl.
The site works Ok, but when I insert a record all the fields look well except for the blob field.


Step to reproduce

Code in snippet; called after a form post.

// Add request
$request = $modx->newObject('dbRequest');
$filename= $requestfile;
if (file_exists($filename))
  $blob = file_get_contents($filename);
  $blob = '';

$request->save(); // will save 

Observed behavior

No errors.
The file exists on the server.
But content of blobfield is 1 byte and the content is “0”.

Expected behavior

The content of the file (like in the productionversion with php 5.6 and modx 2.6.x) in the database


MODX version: MODX Revolution 2.7.2-pl (traditional)
Databasetype: mysql
Database version: 10.4.11-MariaDB
Database characterset: latin1

I hope someone has a hint. I even tried this: delete the table and recreate it with migx; no luck.

file_get_contents will return false if the file doesn’t exist or can’t be read - perhaps a permissions issue?

I checked the file/blob length:

$modx->log(modX::LOG_LEVEL_ERROR, $filename." " .strlen($blob));

C:/xampp/htdocs-portal/assets/uploads/temp/2020-02-06_8-13-30_aaac123456789012q_activationrequest.zip **10418**

I think the content is Ok, but the save to database fails. I use the latest version: migx-2.12.0-pl.

Some extra information:

I have used to debugflag of migx to get more output. It confirms that the data is there:

[2020-02-06 08:27:14] (DEBUG @ C:\xampp\htdocs-portal\core\xpdo\om\xpdoobject.class.php : 1446) Executing SQL:
INSERT INTO `modx_my_requests` (`product_id`, `creationdate`, `file`) VALUES (:product_id, :creationdate, :file
with bindings:
    [:product_id] => Array
            [value] => 271
            [type] => 1

    [:creationdate] => Array
            [value] => 2020-02-06 08:27:14
            [type] => 2

    [:file] => Array
            [value] => PK    $BgM¾ȗ+=$  텠    <etcetera>

But the file content is still not stored in the database.

I think I found a solution. I added some code to xpdoobject.class.php. (in folder core\xpdo\om).

        elseif ($this->_fieldMeta[$_k]['phptype'] == 'timestamp' && preg_match('/int/i', $this->_fieldMeta[$_k]['dbtype'])) {
            $fieldType= PDO::PARAM_INT;
		elseif ($this->_fieldMeta[$_k]['phptype'] == 'binary') { <==== starts here
        elseif (!in_array($this->_fieldMeta[$_k]['phptype'], array ('string','password','datetime','timestamp','date','time','array','json','float'))) {
            $fieldType= PDO::PARAM_INT;
            $this->xpdo->log(xPDO::LOG_LEVEL_ERROR, $this->_fieldMeta[$_k]['phptype']);

Without this change the fieldType=PARAM_INT.

This solves my problem with storing the data in the database, but is the problem caused by a misconfiguration or is it a bug?

Guess you’re using an as-of-yet unsupported phptype in the schema. Sounds like it’s worth reporting it in the xPDO GitHub repository to add that in a future release. Your fix could even be the basis for a proper pull request :wink: