Skip to content
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

Bind type ignored if the value is non-scalar #2752

Closed
kbtz opened this issue Aug 27, 2014 · 5 comments
Closed

Bind type ignored if the value is non-scalar #2752

kbtz opened this issue Aug 27, 2014 · 5 comments
Labels
not a bug Reported issue is not a bug

Comments

@kbtz
Copy link

kbtz commented Aug 27, 2014

Here's my context: after a model fetch, when the column type is DATETIME, the value gets automatically converted to a custom DateTime class. This DateTime implements the magic method __toString so it can be used as a string value too.

When saving the value back to db, the implicit conversion works fine but the value isn't bound to the query and the quotes are missing. This MySQL query was generated by calling $user->save();:

UPDATE `user` SET `login` = ?, `pass` = ?, `last_notified` = 2014-06-04 21:32:40
WHERE `id` = ? 

I've checked $this->modelsMetadata->getBindTypes($user); and the bind type for last_notified is indeed BIND_PARAM_STR.

@phalcon
Copy link
Collaborator

phalcon commented Aug 27, 2014

Try casting the value before assigning the property:

$robots->date = (string) $date;

@phalcon phalcon added the not a bug Reported issue is not a bug label Nov 13, 2014
@andresgutierrez
Copy link
Sponsor Contributor

Closed as not a bug

@lcdennison
Copy link

This still seems like a bug, or at least a missing piece of functionality. Consider these two cases below.

Here we have a custom DateTime_Custom class that simply adds a __toString() method for conversion (since the base DateTime class doesn't have that).

class DateTime_Custom extends \DateTime {
	public function __toString(): string {
		return $this->format('Y-m-d H:m:s');
	}
}

Here we have case 1, where we set a property (i.e. DB field) to the DateTime_Custom object.

$robot = Robot()::findFirst();
$robot->datetime_field = new DateTime_Custom('now');
$robot->save();

This produces a SQL error because the field value for datetime_field is not bound or escaped. This is the specific SQL it produces:

UPDATE `robots` SET `datetime_field` = 2017-09-04 00:56:31 WHERE `id` = ?

However, if we force a cast during the assignment of the property, like this:

$robot = Robot()::findFirst();
$robot->datetime_field = (string) new DateTime_Custom('now');
$robot->save();

Then, the value is properly bound and the SQL produced is:

UPDATE `robots` SET `datetime_field` = ? WHERE `id` = ?

But, why do we need to force a cast to string during assignment of the property? The whole point is for us to be able to interact with the property as a DateTime_Custom object, and then Phalcon converts it to a string (by the DateTime_Custom->__toString() method) when it actually prepares SQL for saving. By the first case above, Phalcon is clearly aware of the __toString() method because it's giving the proper date value. The problem is that Phalcon is not properly understanding that it's a string and binding it as such.

As @cvsguimaraes noted, though, the bind type within the modelsMetadata->getBindTypes() method is listed as BIND_PARAM_STR. So, why doesn't Phalcon know to bind as a string on model save, same as always? That seems like a bug or piece of missing functionality to me, so I think this should be reopened. If I'm going wrong somewhere with this logic, please let me know your thoughts.

@sergeyklay
Copy link
Member

@ldennison Could you please open a new separated issue with code to reproduce

@lcdennison
Copy link

Done, at #13058.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
not a bug Reported issue is not a bug
Projects
None yet
Development

No branches or pull requests

4 participants