oscarotero / simple-crud

PHP library to provide magic CRUD in MySQL/Sqlite databases with zero configuration
MIT License
242 stars 58 forks source link

Last tier select returns array instead of string as column value #39

Closed lookingdown closed 4 years ago

lookingdown commented 4 years ago

Thanks for a surprisingly good library. I have a question regarding the last tier of querys that returns an array instead of a string

$post = $db->post[242]; I get an Object $post->category->name; I get a string $post->user->username; I get a string $post->user->user_info->first_name; I expect to get a string but get an array like so:
array(1) { [""]=> string(7) "Eduardo" }

That I can access as $storevariable[""]

Is this expected behaviour ? or am I doing something wrong.

I merge the result of all this to create an array of the data for the template and of course I can use "first_name"=>$post->user->user_info->first_name[""] for that part if this is how it is supposed to work, I find this library very useful and hope you will keep it up.

Query sequence included below for reference.. data from tracy through this https://github.com/lookingdown/pdo-plus/blob/master/tracyDBbar.php adapted to simple-crud

/thanks

SELECT post.id, post.date, post.title, post.name, post.user_id, post.seo_id, post.author_image, post.image, post.category_id, post.tags, post.post_data, post.views, post.status, post.event, post.eventdate, post.featured, post.location, post.comment, post.gallery_id, post.author_info, post.deleted FROM post WHERE id = :1 LIMIT 1 | {"1":242}

SELECT category.id, category.name, category.info, category.sys_name, category.deleted FROM category LEFT JOIN post ON post.category_id = category.id WHERE post.id = :1 LIMIT 1 | {"1":242}

SELECT user.id, user.username, user.password, user.email, user.locale_id, user.verified, user.banned, user.mod_timestamp FROM user LEFT JOIN post ON post.user_id = user.id WHERE post.id = :1 LIMIT 1 | {"1":242}

SELECT user_info.user_id, user_info.first_name, user_info.last_name, user_info.title, user_info.phone, user_info.address1, user_info.address2, user_info.city, user_info.state, user_info.country, user_info.locale_id, user_info.details, user_info.bio, user_info.facebook, user_info.instagram, user_info.twitter, user_info.whatsapp, user_info.googleplus, user_info.quoted, user_info.newsletter, user_info.image, user_info.active FROM user_info WHERE user_info.user_id = :1 | {"1":7}

oscarotero commented 4 years ago

Mmm, what is the type of the field? Maybe it detects a different field type for "first_name" (See https://github.com/oscarotero/simple-crud#fields)

You can do:

var_dump($db->user_info->first_name);
lookingdown commented 4 years ago

Thanks, its a varchar.. Full dump here :) detects it as string..

object(SimpleCrud\Fields\Field)#76 (3) { ["table":protected]=> object(SimpleCrud\Table)#47 (2) { ["name"]=> string(9) "user_info" ["fields"]=> array(24) { ["user_id"]=> object(SimpleCrud\Fields\Integer)#56 (3) { ["table":protected]=> RECURSION ["info":protected]=> array(7) { ["name"]=> string(7) "user_id" ["type"]=> string(3) "int" ["null"]=> bool(false) ["default"]=> NULL ["unsigned"]=> bool(false) ["length"]=> NULL ["values"]=> NULL } ["config":protected]=> array(0) { } } ["first_name"]=> RECURSION ["last_name"]=> object(SimpleCrud\Fields\Field)#75 (3) { ["table":protected]=> RECURSION ["info":protected]=> array(7) { ["name"]=> string(9) "last_name" ["type"]=> string(7) "varchar" ["null"]=> bool(true) ["default"]=> NULL ["unsigned"]=> bool(false) ["length"]=> int(55) ["values"]=> NULL } ["config":protected]=> array(0) { } } ["fullname"]=> object(SimpleCrud\Fields\Field)#74 (3) { ["table":protected]=> RECURSION ["info":protected]=> array(7) { ["name"]=> string(8) "fullname" ["type"]=> string(7) "varchar" ["null"]=> bool(true) ["default"]=> NULL ["unsigned"]=> bool(false) ["length"]=> int(255) ["values"]=> NULL } ["config":protected]=> array(0) { } } ["title"]=> object(SimpleCrud\Fields\Field)#66 (3) { ["table":protected]=> RECURSION ["info":protected]=> array(7) { ["name"]=> string(5) "title" ["type"]=> string(7) "varchar" ["null"]=> bool(true) ["default"]=> NULL ["unsigned"]=> bool(false) ["length"]=> int(55) ["values"]=> NULL } ["config":protected]=> array(0) { } } ["phone"]=> object(SimpleCrud\Fields\Field)#73 (3) { ["table":protected]=> RECURSION ["info":protected]=> array(7) { ["name"]=> string(5) "phone" ["type"]=> string(7) "varchar" ["null"]=> bool(true) ["default"]=> NULL ["unsigned"]=> bool(false) ["length"]=> int(20) ["values"]=> NULL } ["config":protected]=> array(0) { } } ["address1"]=> object(SimpleCrud\Fields\Field)#72 (3) { ["table":protected]=> RECURSION ["info":protected]=> array(7) { ["name"]=> string(8) "address1" ["type"]=> string(7) "varchar" ["null"]=> bool(true) ["default"]=> NULL ["unsigned"]=> bool(false) ["length"]=> int(45) ["values"]=> NULL } ["config":protected]=> array(0) { } } ["address2"]=> object(SimpleCrud\Fields\Field)#71 (3) { ["table":protected]=> RECURSION ["info":protected]=> array(7) { ["name"]=> string(8) "address2" ["type"]=> string(7) "varchar" ["null"]=> bool(true) ["default"]=> NULL ["unsigned"]=> bool(false) ["length"]=> int(45) ["values"]=> NULL } ["config":protected]=> array(0) { } } ["city"]=> object(SimpleCrud\Fields\Field)#69 (3) { ["table":protected]=> RECURSION ["info":protected]=> array(7) { ["name"]=> string(4) "city" ["type"]=> string(7) "varchar" ["null"]=> bool(true) ["default"]=> NULL ["unsigned"]=> bool(false) ["length"]=> int(45) ["values"]=> NULL } ["config":protected]=> array(0) { } } ["state"]=> object(SimpleCrud\Fields\Field)#68 (3) { ["table":protected]=> RECURSION ["info":protected]=> array(7) { ["name"]=> string(5) "state" ["type"]=> string(7) "varchar" ["null"]=> bool(true) ["default"]=> NULL ["unsigned"]=> bool(false) ["length"]=> int(30) ["values"]=> NULL } ["config":protected]=> array(0) { } } ["country"]=> object(SimpleCrud\Fields\Field)#70 (3) { ["table":protected]=> RECURSION ["info":protected]=> array(7) { ["name"]=> string(7) "country" ["type"]=> string(7) "varchar" ["null"]=> bool(true) ["default"]=> NULL ["unsigned"]=> bool(false) ["length"]=> int(45) ["values"]=> NULL } ["config":protected]=> array(0) { } } ["locale_id"]=> object(SimpleCrud\Fields\Integer)#79 (3) { ["table":protected]=> RECURSION ["info":protected]=> array(7) { ["name"]=> string(9) "locale_id" ["type"]=> string(7) "varchar" ["null"]=> bool(true) ["default"]=> string(5) "en_US" ["unsigned"]=> bool(false) ["length"]=> int(30) ["values"]=> NULL } ["config":protected]=> array(0) { } } ["details"]=> object(SimpleCrud\Fields\Field)#81 (3) { ["table":protected]=> RECURSION ["info":protected]=> array(7) { ["name"]=> string(7) "details" ["type"]=> string(4) "text" ["null"]=> bool(true) ["default"]=> NULL ["unsigned"]=> bool(false) ["length"]=> NULL ["values"]=> NULL } ["config":protected]=> array(0) { } } ["bio"]=> object(SimpleCrud\Fields\Field)#82 (3) { ["table":protected]=> RECURSION ["info":protected]=> array(7) { ["name"]=> string(3) "bio" ["type"]=> string(4) "text" ["null"]=> bool(true) ["default"]=> NULL ["unsigned"]=> bool(false) ["length"]=> NULL ["values"]=> NULL } ["config":protected]=> array(0) { } } ["facebook"]=> object(SimpleCrud\Fields\Field)#83 (3) { ["table":protected]=> RECURSION ["info":protected]=> array(7) { ["name"]=> string(8) "facebook" ["type"]=> string(7) "varchar" ["null"]=> bool(true) ["default"]=> NULL ["unsigned"]=> bool(false) ["length"]=> int(255) ["values"]=> NULL } ["config":protected]=> array(0) { } } ["instagram"]=> object(SimpleCrud\Fields\Field)#84 (3) { ["table":protected]=> RECURSION ["info":protected]=> array(7) { ["name"]=> string(9) "instagram" ["type"]=> string(7) "varchar" ["null"]=> bool(true) ["default"]=> NULL ["unsigned"]=> bool(false) ["length"]=> int(255) ["values"]=> NULL } ["config":protected]=> array(0) { } } ["twitter"]=> object(SimpleCrud\Fields\Field)#85 (3) { ["table":protected]=> RECURSION ["info":protected]=> array(7) { ["name"]=> string(7) "twitter" ["type"]=> string(7) "varchar" ["null"]=> bool(true) ["default"]=> NULL ["unsigned"]=> bool(false) ["length"]=> int(255) ["values"]=> NULL } ["config":protected]=> array(0) { } } ["whatsapp"]=> object(SimpleCrud\Fields\Field)#86 (3) { ["table":protected]=> RECURSION ["info":protected]=> array(7) { ["name"]=> string(8) "whatsapp" ["type"]=> string(7) "varchar" ["null"]=> bool(true) ["default"]=> NULL ["unsigned"]=> bool(false) ["length"]=> int(255) ["values"]=> NULL } ["config":protected]=> array(0) { } } ["googleplus"]=> object(SimpleCrud\Fields\Field)#87 (3) { ["table":protected]=> RECURSION ["info":protected]=> array(7) { ["name"]=> string(10) "googleplus" ["type"]=> string(7) "varchar" ["null"]=> bool(true) ["default"]=> NULL ["unsigned"]=> bool(false) ["length"]=> int(255) ["values"]=> NULL } ["config":protected]=> array(0) { } } ["quoted"]=> object(SimpleCrud\Fields\Field)#88 (3) { ["table":protected]=> RECURSION ["info":protected]=> array(7) { ["name"]=> string(6) "quoted" ["type"]=> string(4) "text" ["null"]=> bool(true) ["default"]=> NULL ["unsigned"]=> bool(false) ["length"]=> NULL ["values"]=> NULL } ["config":protected]=> array(0) { } } ["newsletter"]=> object(SimpleCrud\Fields\Integer)#89 (3) { ["table":protected]=> RECURSION ["info":protected]=> array(7) { ["name"]=> string(10) "newsletter" ["type"]=> string(7) "tinyint" ["null"]=> bool(true) ["default"]=> string(1) "0" ["unsigned"]=> bool(false) ["length"]=> int(1) ["values"]=> NULL } ["config":protected]=> array(0) { } } ["userimage"]=> object(SimpleCrud\Fields\Field)#90 (3) { ["table":protected]=> RECURSION ["info":protected]=> array(7) { ["name"]=> string(9) "userimage" ["type"]=> string(7) "varchar" ["null"]=> bool(true) ["default"]=> NULL ["unsigned"]=> bool(false) ["length"]=> int(255) ["values"]=> NULL } ["config":protected]=> array(0) { } } ["image"]=> object(SimpleCrud\Fields\Field)#91 (3) { ["table":protected]=> RECURSION ["info":protected]=> array(7) { ["name"]=> string(5) "image" ["type"]=> string(7) "varchar" ["null"]=> bool(true) ["default"]=> NULL ["unsigned"]=> bool(false) ["length"]=> int(255) ["values"]=> NULL } ["config":protected]=> array(0) { } } ["active"]=> object(SimpleCrud\Fields\Boolean)#92 (3) { ["table":protected]=> RECURSION ["info":protected]=> array(7) { ["name"]=> string(6) "active" ["type"]=> string(7) "tinyint" ["null"]=> bool(true) ["default"]=> string(1) "0" ["unsigned"]=> bool(false) ["length"]=> int(1) ["values"]=> NULL } ["config":protected]=> array(0) { } } } } ["info":protected]=> array(7) { ["name"]=> string(10) "first_name" ["type"]=> string(7) "varchar" ["null"]=> bool(false) ["default"]=> NULL ["unsigned"]=> bool(false) ["length"]=> int(45) ["values"]=> NULL } ["config":protected]=> array(0) { } }

lookingdown commented 4 years ago

Directly on the field it is correct string(7) "Eduardo" var_dump on --> $db->user_info->get(['user_id' => 13])->first_name // returns: string(7) "Eduardo" Correct!

$db->user[13]->user_info->first_name // returns: array(1) { [""]=> string(7) "Eduardo" } Unexpected!

lookingdown commented 4 years ago

No id or PK on that table, Added id and PK (id) just to test but makes not difference.. same result just the resulting array get the key of the id of user_info like so array(1) { [2]=> string(7) "Eduardo" } if that helps explain anything..

oscarotero commented 4 years ago

Ok, got it. This is because you're getting the value from a RowCollection instead a Row:

$post = $db->post[23]; //This returns a Row
$post->comments; //This returns a RowCollection with all comments related with the post
$post->comments->text; //This returns an array with all values of "text" field of all comments, using the id as key.

So, seems like the relation between user and user_info is not direct: 1 user can have several user_info.

lookingdown commented 4 years ago

Not sure that is possible that 1 user can have several user_info only one user_info per user linked by user.id to user_info.user_id would not be possible with more than one... $db->user[3]->user_info->first_name returns an array instead of the column value one result all the same just in the form of key=>value instead...

oscarotero commented 4 years ago

If the relation is in user_info.user_id, it's possible to have several user_info rows with the same user_id. You should do the opposite: move the relation to the field user.user_info_id.

lookingdown commented 4 years ago

For some reason simple-crud believes (or interprets) the relation is one to many due to the reference being in the second table (user_id) user.id = user_info.user_id Something with the logic of how the query builder interterprets the relation. I think it should work all the same but it does not.

When I turn it around to user.user_info_id = user_info.id it works and return the expected string without any problem.. :)..

What do you think.. Do something about it or leave it be.. :)

oscarotero commented 4 years ago

The library works fine. $post->comment is not the same as $comment->post, the first one returns a collection and the second one a row. These interpretations are created according with naming conventions explained here: https://github.com/oscarotero/simple-crud#naming-conventions

lookingdown commented 4 years ago

Thank you..
relation between user.id & user_info.user_id is not the same as between user.user_info_id & user_info.id is not the same in this case then,.. will update my code and the fk between these tables accordingly.. Thanks a lot