NotionCommotion
Members-
Posts
2,446 -
Joined
-
Last visited
-
Days Won
10
Everything posted by NotionCommotion
-
Converting collection of objects to JSON
NotionCommotion replied to NotionCommotion's topic in PHP Coding Help
Thanks gizmola, I certainly hope I am drinking the doctrine coolaid for a good reason! RDBs "kind of" support inheritance using supertype/subtype, don't you think? I was looking closer at your referenced serializer link. First of all, other than dealing with recursion, what is the point of using it instead of plain old json_encode()? Secondly, the documentation states that the most common use is serializing an object, but when I try the following, somehow the script just ends and returns nothing (I haven't totally tracked it down yet). Don't know if it matters but I am using xml to define my doctrine entities. Maybe I need to define what it returns? $serializer = \JMS\Serializer\SerializerBuilder::create()->build(); $serializer->serialize($someEntity, 'json') -
Converting collection of objects to JSON
NotionCommotion replied to NotionCommotion's topic in PHP Coding Help
@kicken As always, good advice. Thank you. @gizmola Yes, a REST api. No, I am not and haven't ever tried Symfony (well, I guess I use Twig). Using a formal ORM for the first time. While I like a lot of Doctrine's capabilities, I really don't know yet if I am glad I am trying to adapt it. Actually, I know I am not glad but hope/expect that will change. I probably should look into Symfony, but this Doctrine thing has taken me for a loop. Good news is doing so has allowed me to actually understand some previously foreign concepts that smart programmers on this forum believe are important. Thanks -
Converting collection of objects to JSON
NotionCommotion replied to NotionCommotion's topic in PHP Coding Help
I suppose I too don't understand why I am not just overriding getB(). My need is just to allow it to be flexible enough should two classes be slightly different. I thought the intent was for the JSON Schema to validate JSON documents. I will read in more detail. I actually wrote my own classes to validate JSON and wish I learned about this sooner. If I understand you correctly, I will need to have the entities responsible for obtaining the data included in the JSON but just should use a separate method instead of the JsonSerialize(). I got schooled a while back by ignace that a separate class should always be responsible to do so and was looking for ways to do so. -
Converting collection of objects to JSON
NotionCommotion replied to NotionCommotion's topic in PHP Coding Help
Thanks kicken, JSON Schema looks interesting, but I am not sure it is an answer. Let's say we have a collection (or array) containing 6 objects. Array ( [0] => ProjectC Object ( [c:protected] => 5 [g:protected] => 5 [h:protected] => 2 [a:protected] => 1 [b:protected] => 3 [d:protected] => 5 ) [1] => ProjectA Object ( [b:protected] => 4 [d:protected] => 2 [e:protected] => 7 [f:protected] => 8 [a:protected] => 1 [c:protected] => 2 ) [2] => ProjectB Object ( [bDiffName:protected] => 1 [c:protected] => 4 [d:protected] => 2 [g:protected] => 3 [a:protected] => 1 [b:protected] => 3 ) [3] => ProjectB Object ( [bDiffName:protected] => 1 [c:protected] => 4 [d:protected] => 2 [g:protected] => 3 [a:protected] => 1 [b:protected] => 3 ) [4] => ProjectC Object ( [c:protected] => 5 [g:protected] => 5 [h:protected] => 2 [a:protected] => 1 [b:protected] => 3 [d:protected] => 5 ) [5] => ProjectA Object ( [b:protected] => 4 [d:protected] => 2 [e:protected] => 7 [f:protected] => 8 [a:protected] => 1 [c:protected] => 2 ) ) $a should not be included in any of the JSON output. ProjectB uses $bDiffName instead of $b. Some objects provide have additional properties which should be included. As such, the desired output should be as shown. [ {"b":3,"c":5,"d":5,"g":5,"h":5}, {"b":4,"c":2,"d":2,"e":7,"f":8}, {"b":1,"c":4,"d":2,"g":3}, {"b":1,"c":4,"d":2,"g":3}, {"b":3,"c":5,"d":5,"g":5,"h":5}, {"b":4,"c":2,"d":2,"e":7,"f":8} ] Sure, I can write a class to present the results as needed. But if so, each object needs its own, no? And if i write a separate class for each, without making the entity responsible to identify the applicable class or without making some map between entity class name and serializing service, how can the script know which class to use? Reference code only... <?php abstract class Project implements JsonSerializable { protected $a=1, $b=3, $c=2, $d=5; public function getB(){return $this->b;} public function getC(){return $this->c;} public function getD(){return $this->d;} } class ProjectA extends Project { protected $b=4, $d=2, $e=7, $f=8; public function getE(){return $this->e;} public function getF(){return $this->f;} public function jsonSerialize() { return ['b'=>$this->getB(),'c'=>$this->getC(),'d'=>$this->getD(),'e'=>$this->getE(),'f'=>$this->getF()]; } } class ProjectB extends Project { protected $bDiffName=1, $c=4, $d=2, $g=3; public function getBDiffName(){return $this->bDiffName;} public function getG(){return $this->g;} public function jsonSerialize() { return ['b'=>$this->getBDiffName(),'c'=>$this->getC(),'d'=>$this->getD(),'g'=>$this->getG()]; } } class ProjectC extends Project { protected $c=5, $g=5, $h=2; public function getG(){return $this->g;} public function getH(){return $this->g;} public function jsonSerialize() { return ['b'=>$this->getB(),'c'=>$this->getC(),'d'=>$this->getD(),'g'=>$this->getG(),'h'=>$this->getH()]; } } $arr=[ new ProjectC, new ProjectA, new ProjectB, new ProjectB, new ProjectC, new ProjectA, ]; echo('<pre>'.print_r($arr,1).'</pre>'); echo('<pre>'.json_encode($arr).'</pre>'); -
I can obtain either one or a collection of objects by executing the following. $product = $entityManager->find('Product', $id); $products = $entityManager->getRepository('Product')->findAll(); All products have many common properties, however, based on the type of product there are some differences. To implement this, I am using class table inheritance (side question - is there any difference between CTI and supertype/subtype modeling?). I will need to convert either a single product to JSON as well as a collection of products to JSON. When converting a collection, only a subset of the product's properties is desired, however, again most of these properties are common to each product type but there are some differences. One solution is to utilize the JsonSerializable interface. A shortcoming, however, is how to deal with both the detail view with all the properties and the collection view with only a subset of properties. To overcome this, I can potentially use jsonSerialize() to provide the detail view, and add another function index() to provide the subset results for the collection. Since this index() function will not recursively incorporate sub-objects, I will need to manually loop over the collection, however, it should not be too big of issue. Or should the entity not be responsible to convert to JSON? I am kind of mixed on this issue, but do agree using a separate class has merit. So, if a separate class is used, how does it deal with each subclass of Product which might have unique properties and getters? I suppose I can have the entities implement an interface which requires them to return their applicable properties, but doing so isn't very flexible and isn't this (almost) the same as having the entity responsible to provide the JSON? I "could" make this other class perform some switch operation based on the class name, but doing so goes against all good OOP principles. What is the "right" way to do this? Thanks
-
Since you are okay with your application relying on JavaScript, there is no need for PHP for this portion. Customer alters quantities on form_1 and when transitioning to form_2, just use JavaScript to copy the values you want to the hidden inputs. <script> function update(){ var quantity = document.getElementById("quantity"); var total = document.getElementById("total"); total.value = (quantity.value * 5); document.getElementById("q").value=quantity; document.getElementById("t").value=total; } </script> <form action="FINISHED.php" method="post"> <input type="submit" value="FINISHED"> <input type="hidden" name="q" id="q" value=""> <input type="hidden" name="t" id="t" value=""> </form> You need to get your head around what the client (i.e. your web browser) and server (i.e. PHP) is. The client always makes the request and the server only responds. The server cannot directly change anything on the client. If the client receives the code <?=$_POST["quantity"]?>, it will just be interpreted as this exact literal text. Only the server knows that it should replace this code with the value of $_POST['quantity']. Similarly, the server doesn't have access to the JavaScript variable "quantity" or "total". The only way data is shared is when the client sends some data to the server or the server responds to the client with some data. The client sends data to the server either by submitting the page or by submitting via an Ajax request, and for both cases the server responds with whatever it was instructed to do provide. You "could" make the client submit form_ and have the server respond with form_2 with certain inputs filled out using an echo statement. Or you can make the client under form_1 update form_2 with the correct values and submit form_2. And really "kind of" the same thing, you can make the client perform an Ajax request to send (and receive) data without submitting the form. Make extra, extra, extra sure you understand this.
-
Not saying necessarily that your PHP doesn't have errors, but that error in particular wasn't a PHP error by a SQL error. Yes, I thought but wasn't positive that order and including all the fulltext indexes was required.
-
I don't have too much experience with fulltext indexes. It isn't a PHP issue anymore but a SQL issue, and as such, I would recommend eliminating variables and running your query directly from the command line or through some SQL client if you wish. Maybe try the following? SELECT COUNT(*) as tot FROM television p WHERE MATCH(title,description,keywords) AGAINST(? IN BOOLEAN MODE);
-
What have you tried? SHOW INDEX FROM television; ALTER TABLE television ADD FULLTEXT(title,keywords);
-
You are using PDO in your later code which is good. You next need to create a PDO connection. The docs give an example which was copied below. Obviously, you want to rename $dbh to $db. Note that if you simple searched "php pdo", the first result would be http://php.net/manual/en/book.pdo.php which doesn't give any examples. Instead of randomly going through each link (which isn't necessarily a waste of time), always check the __construct link first. PS. Get rid of all your constant definitions for your database connection values. At first you might think it is a good idea, but having too many constants gets complicated fast. I like to locate a file called config.ini in a secure location (i.e. not in your public root directory!) and use parse_ini_file() to convert it into an array. <?php /* Connect to a MySQL database using driver invocation */ $dsn = 'mysql:dbname=testdb;host=127.0.0.1'; $user = 'dbuser'; $password = 'dbpass'; try { $dbh = new PDO($dsn, $user, $password); } catch (PDOException $e) { echo 'Connection failed: ' . $e->getMessage(); } ?>
-
Creating new objects with sub-objects when using an ORM
NotionCommotion replied to NotionCommotion's topic in PHP Coding Help
I think I answered half of my questions. If AggrPoint#aggrType should be an object (which I believe it should be), then I should use a factory pattern and have each factory retrieve the correct instance of AggrType and then either inject it in AggrPoint or use AggrPoint's setAggrType() method. I am not really sure whether TimeUnit should be an object, and still need to figure out how to prevent Doctrine from generating an object but still keep the foreign key constant. -
Creating new objects with sub-objects when using an ORM
NotionCommotion replied to NotionCommotion's topic in PHP Coding Help
Another example of the same issue is TimeUnit. I have a table which contains only eight records which correspond to seconds, minutes, hours, days, weeks, months, quarters, and years. This table has two purposes: 1) Create the list of options to present to the user. 2) Provide referential integrity. I can make AggrPoint#timeUnit either a primitive type (integer or string) or an object. Both approaches seem to have merit. What would you do? If a string, how can Doctrine be used to generate the foreign key constraint? If an object, how should an instance of one of these eight TimeUnit objects be obtained when creating a new AggrPoint? -
I have the following three tables (and also delta_point and hist_point which are purposely left out and just mentioned for context). Before going down the Doctrine ORM long curvy road, aggrType was just used to restrict possible values so that I didn't need to use MySQL's ENUM, but now I am thinking there may be value to making it an entity and include some methods (and a second reason because I still can't figure out how to make Doctrine create a FK constraint yet not populate the parent entity with a AggrType object). point -id (int PK) -data -dType /* descriminator. Options are AggregatePoint, DeltaPoint, and HistoricPoint */ aggr_point -id (int PK, FK to point) -aggrType (char FK to aggrType) -data aggrType -type (char PK) /* there are about five types */ I have a service to create a new point based on the provided desired type and user data. I don't like the switch statement to determine which type of point to create, but don't know a better way. Also my entity is responsible to provide the appropriate validation rules for the given point type which might not be considered proper but it seems to work for me. Any constructive criticism is welcomed. <?php namespace NotionCommotion\PointMapper\Api\Point; use NotionCommotion\PointMapper\Domain\Entity\Point; class PointService { public function create(string $type, array $params):integer { $class=[ 'aggr'=>'AggregatePoint', 'delta'=>'DeltaPoint', 'hist'=>'HistoricPoint', ][$type]; //$class='Point\\'.$class; //This doesn't seem to be possible and I needed to use the fully qualifed name without the short cut used namespace. $class='\\Greenbean\Datalogger\Domain\Entity\Point\\'.$class; $point=new $class(); $validator=$this->getValidator($point); $params=$validator->sanitize($params); $validator->validate($params); $point->setAccount($this->account); $point->populate($params, $this->em); //Will be addressed later $this->em->persist($point); $this->em->flush(); $point->setIdPublic($this->em->getRepository(Point\Point::class)->getPublicId($point->getId())); return $point->getIdPublic(); } } Now, this is the part I am struggling with the most. I only have one service to create any type of point, so I do wish to put a bunch of if/thens in it and instead move logic to the individual point type being created. The AggrPoint in question requires a sub-point and I don't think it is appropriate to inject the entity manager into a point entity and as an alternative solution find an existing point which is associated with the account which resides in the new AggrPoint. Maybe not appropriate, but it works. This type of point also has a sub-object AggrType as discussed at the very beginning of this post, so I first attempt to create a new one from scratch, but that doesn't work and I need to set $aggrType with an existing one. As an alternative, I passed the entity the entity manager, but as stated I think this is a bad idea. Any recommendations where to go from here? Thank you namespace NotionCommotion\PointMapper\Domain\Entity\Point; class AggregatePoint extends Point { public function populate(array $params, \Doctrine\ORM\EntityManager $em):\NotionCommotion\PointMapper\Domain\Entity\Entity{ $criteria = \Doctrine\Common\Collections\Criteria::create() ->where(\Doctrine\Common\Collections\Criteria::expr()->eq("id_public", $params['pointId'])); if(!$subpoint = $this->getAccount()->getPoints()->matching($criteria)->current()){ throw new \Exception("Invalid subpoint ID $params[pointId]"); } $this->setSubpoint($subpoint); //This won't work since I must use an existing AggregateType and not create a new one $aggrType=new AggregateType(); $aggrType->setType($params['aggrType']); //This just seems wrong and I shouldn't be passing the entity manager to an entity $aggrType=$em->getRepository(AggregateType::class)->findOneBy(['type'=>$params['aggrType']]); $this->setAggregateType($aggrType); unset($params['pointId'], $params['aggrType']); // parent::populate($params) not shown, but it basically calles appropriate setters based on the property name return parent::populate($params); } public function getValidatorRules():array { return $this->filesToArr(['/point/base.json', '/point/aggr.json']); } }
-
Is it possible to have a class access another class it its parent directory without using a fully qualified name? While the following script is not valid, it is how I would have thought it would be done should it be possible. If it is not possible, I expect there is a good reason why one would not want to do so, and would appreciate your thoughts why that is so. Thanks // src/PrimaryTopic/SubTopic/SubSubTopic/ParentClass.php namespace PrimaryTopic\SubTopic\SubSubTopic; class ParentClass {} // src/PrimaryTopic/SubTopic/SubSubTopic/Child/ChildClass1.php namespace PrimaryTopic\SubTopic\SubSubTopic\Child; class ChildClass1 extends ..\ParentClass {} // src/PrimaryTopic/SubTopic/SubSubTopic/Child/ChildClass2.php namespace PrimaryTopic\SubTopic\SubSubTopic\Child; class ChildClass2 extends ..\ParentClass {}
-
Steven, My mistake and not yours. If you have a PHP array or object, you use json_encode() to encode it into a JSON string. Conversely, you use json_decode() to convert a JSON string into either a std object or an array (by passing TRUE as the second argument). Don't be afraid of arrays!!! They are too important.
-
See http://php.net/manual/en/function.json-decode.php
-
As I think you figured out in your second post, it is not an array but a stdClass object. The method to access arrays and objects is different and cannot be interchanged. $results will be a string, and not an array nor an object. You must use $myObj=json_encode($result) to access as an object or $myArr=json_encode($result, true) to access as an array.
-
Organizing related applications
NotionCommotion replied to NotionCommotion's topic in PHP Coding Help
Thanks kicken, I currently use separate domains but will also go with separate repositories as you recommend. I was original thinking the Domain (I've been going down the ORM journey and I am currently thinking the domain consists of the Entities and Repositories) would need to exist under both the main and admin apps, but now am thinking it should exist independent of each and exist on its own as it reflects the business logic and database which is used by both sites. On a related note, I was reading this post which promotes organizing by "module"... src/ BasketModule/ Basket.php BasketService.php BasketRepository.php ORM/ Basket.orm.yml ProductModule/ Product.php ProductService.php ProductRepository.php ORM/ Product.orm.yml instead of the "classical" layout... src/ Entity/ Product.php Basket.php Service/ ProductService.php BasketService.php Repository/ ProductRepository.php BasketRepository.php Resources/ ORM/ Product.orm.yml Basket.orm.yml At first I thought it was a good idea, but now am thinking the Repository script can possibly span multiple entities and I will probably keep with a modified classical layout. -
Organizing related applications
NotionCommotion replied to NotionCommotion's topic in PHP Coding Help
@ginerjm, I have yet to see a single comment from you that provides any value. Please refrain from responding to any of my posts. Thank you -
I have two related websites which utilize the same database: Main website for public use. Admin website for administration purposes. Currently, I have both located in /var/www/combined-app which is a single git repository and contains the following: /var/www/combined-app/ public/ public-admin/ src/ main/ admin/ vendor/ composer.json bootstrap.php Alternatively, I could have done the following: /var/www/combined-app/ main/ public/ src/ vendor/ composer.json bootstrap.php admin/ public/ src/ vendor/ composer.json bootstrap.php Or maybe something else all together? Is one approach typically better than the other? If so, please provide reasons why. If my second example, would you recommend separate git repositories for main and admin? Thanks
-
Doctrine, Composer, and namespace
NotionCommotion replied to NotionCommotion's topic in PHP Coding Help
Yes, I am glad too. Does it look like it is all being done "correctly"? -
Doctrine, Composer, and namespace
NotionCommotion replied to NotionCommotion's topic in PHP Coding Help
Immediate issue solved. It appears that all extended classes (and not just intermediate extended classes) need to included in the grandparent's explicit distriminatorMap. Also, at least one of the intermediate extended classes needs to have an explicit distriminatorMap. Also, the distriminatorColumn needs to be defined in any extended classes (i.e. AirVehicles and GroundVehicles) which also extend other classes, and needs to use the same name as the grandparent's distriminatorColumn. I didn't come across any documentation to this effect, but it seems to work as desired. #MyNamespace.MyApp.Vehicle.Vehicle.dcm.yml MyNamespace\MyApp\Vehicle\Vehicle: type: entity table: vehicle_table inheritanceType: JOINED discriminatorColumn: name: discriminator_column type: string discriminatorMap: vehicle: Vehicle airvehicle: MyNamespace\MyApp\Vehicle\AirVehicle\AirVehicle car: MyNamespace\MyApp\Vehicle\GroundVehicle\Car\Car train: MyNamespace\MyApp\Vehicle\GroundVehicle\Train\Train groundvehicle: MyNamespace\MyApp\Vehicle\GroundVehicle\GroundVehicle airplane: MyNamespace\MyApp\Vehicle\AirVehicle\Airplane\Airplane rocket: MyNamespace\MyApp\Vehicle\AirVehicle\Rocket\Rocket repositoryClass: VehicleRepository id: id: type: integer generator: strategy: AUTO fields: grandParentItem1: type: string grandParentItem2: type: string #MyNamespace.MyApp.Vehicle.AirVehicle.AirVehicle.dcm.yml MyNamespace\MyApp\Vehicle\AirVehicle\AirVehicle: type: entity table: air_vehicle extends: MyNamespace\MyApp\Vehicle\Vehicle inheritanceType: JOINED discriminatorColumn: name: discriminator_column type: string discriminatorMap: airVehicle: AirVehicle airplane: MyNamespace\MyApp\Vehicle\AirVehicle\Airplane\Airplane rocket: MyNamespace\MyApp\Vehicle\AirVehicle\Rocket\Rocket repositoryClass: AirVehicleRepository id: id: associationKey: true fields: parentItem1: type: string parentItem2: type: string <?php //use MyNamespace\MyApp; error_reporting(E_ALL); ini_set("log_errors", '1'); ini_set('display_startup_errors', '1'); ini_set('display_errors', '1'); require_once "../bootstrap.php"; function createObj($em, $class) { $cn=explode('\\', $class); $cn=$cn[count($cn)-1]; $entity = new $class(); $entity->setChildItem1("$cn c1"); $entity->setChildItem2("$cn c2"); $entity->setParentItem1("$cn p1"); $entity->setParentItem2("$cn p2"); $entity->setGrandParentItem1("$cn g1"); $entity->setGrandParentItem2("$cn g2"); try{ $em->persist($entity); $em->flush(); echo "Created $class with ID " . $entity->getId() . "\n\n"; } catch(\Exception $e) { echo($class.' - '.$e->getMessage()."\n\n"); } } function displayMember($em, $class, $id) { echo("Display Member $id for $class\n\n"); try{ $member=$em->find($class, $id); print_r($member); } catch(\Exception $e) { echo($class.' - '.$e->getMessage()."\n\n"); } } function displayAllMembers($em, $class) { echo("Diaplay All Members for $class\n\n"); $repository = $em->getRepository($class); try{ $members=$repository->findAll(); print_r($members); } catch(\Exception $e) { echo($class.' - '.$e->getMessage()."\n\n"); } } $entities=[ 'Vehicle'=>['class'=>'\MyNamespace\MyApp\Vehicle\Vehicle','children'=>[ 'AirVehicle'=>['class'=>'\MyNamespace\MyApp\Vehicle\GroundVehicle\GroundVehicle','children'=>[ 'Rocket'=>'\MyNamespace\MyApp\Vehicle\AirVehicle\Rocket\Rocket', 'Airplane'=>'\MyNamespace\MyApp\Vehicle\AirVehicle\Airplane\Airplane' ]], 'GroundVehicle'=>['class'=>'\MyNamespace\MyApp\Vehicle\AirVehicle\AirVehicle','children'=>[ 'Train'=>'\MyNamespace\MyApp\Vehicle\GroundVehicle\Train\Train', 'Car'=>'\MyNamespace\MyApp\Vehicle\GroundVehicle\Car\Car' ]], ] ], ]; //Creating works correctly foreach($entities as $grandparentName=>$grandparent) { //createObj($em, $grandparent['class']); //Abstract foreach($grandparent['children'] as $parentName=>$parent) { //createObj($em, $parent['class']); //Abstract foreach($parent['children'] as $childName=>$class) { createObj($em, $class); } } } displayMember($em, '\MyNamespace\MyApp\Vehicle\AirVehicle\Rocket\Rocket', 1); displayMember($em, '\MyNamespace\MyApp\Vehicle\AirVehicle\AirVehicle', 1); displayMember($em, '\MyNamespace\MyApp\Vehicle\Vehicle', 1); foreach($entities as $grandparentName=>$grandparent) { displayAllMembers($em, $grandparent['class']); foreach($grandparent['children'] as $parentName=>$parent) { displayAllMembers($em, $parent['class']); foreach($parent['children'] as $class) { displayAllMembers($em, $class); } } } Created \MyNamespace\MyApp\Vehicle\AirVehicle\Rocket\Rocket with ID 5 Created \MyNamespace\MyApp\Vehicle\AirVehicle\Airplane\Airplane with ID 6 Created \MyNamespace\MyApp\Vehicle\GroundVehicle\Train\Train with ID 7 Created \MyNamespace\MyApp\Vehicle\GroundVehicle\Car\Car with ID 8 Display Member 1 for \MyNamespace\MyApp\Vehicle\AirVehicle\Rocket\Rocket MyNamespace\MyApp\Vehicle\AirVehicle\Rocket\Rocket Object ( [childItem1:MyNamespace\MyApp\Vehicle\AirVehicle\Rocket\Rocket:private] => Rocket c1 [childItem2:MyNamespace\MyApp\Vehicle\AirVehicle\Rocket\Rocket:private] => Rocket c2 [parentItem1:MyNamespace\MyApp\Vehicle\AirVehicle\AirVehicle:private] => Rocket p1 [parentItem2:MyNamespace\MyApp\Vehicle\AirVehicle\AirVehicle:private] => Rocket p2 [id:MyNamespace\MyApp\Vehicle\Vehicle:private] => 1 [grandParentItem1:MyNamespace\MyApp\Vehicle\Vehicle:private] => Rocket g1 [grandParentItem2:MyNamespace\MyApp\Vehicle\Vehicle:private] => Rocket g2 ) Display Member 1 for \MyNamespace\MyApp\Vehicle\AirVehicle\AirVehicle MyNamespace\MyApp\Vehicle\AirVehicle\Rocket\Rocket Object ( [childItem1:MyNamespace\MyApp\Vehicle\AirVehicle\Rocket\Rocket:private] => Rocket c1 [childItem2:MyNamespace\MyApp\Vehicle\AirVehicle\Rocket\Rocket:private] => Rocket c2 [parentItem1:MyNamespace\MyApp\Vehicle\AirVehicle\AirVehicle:private] => Rocket p1 [parentItem2:MyNamespace\MyApp\Vehicle\AirVehicle\AirVehicle:private] => Rocket p2 [id:MyNamespace\MyApp\Vehicle\Vehicle:private] => 1 [grandParentItem1:MyNamespace\MyApp\Vehicle\Vehicle:private] => Rocket g1 [grandParentItem2:MyNamespace\MyApp\Vehicle\Vehicle:private] => Rocket g2 ) Display Member 1 for \MyNamespace\MyApp\Vehicle\Vehicle MyNamespace\MyApp\Vehicle\AirVehicle\Rocket\Rocket Object ( [childItem1:MyNamespace\MyApp\Vehicle\AirVehicle\Rocket\Rocket:private] => Rocket c1 [childItem2:MyNamespace\MyApp\Vehicle\AirVehicle\Rocket\Rocket:private] => Rocket c2 [parentItem1:MyNamespace\MyApp\Vehicle\AirVehicle\AirVehicle:private] => Rocket p1 [parentItem2:MyNamespace\MyApp\Vehicle\AirVehicle\AirVehicle:private] => Rocket p2 [id:MyNamespace\MyApp\Vehicle\Vehicle:private] => 1 [grandParentItem1:MyNamespace\MyApp\Vehicle\Vehicle:private] => Rocket g1 [grandParentItem2:MyNamespace\MyApp\Vehicle\Vehicle:private] => Rocket g2 ) Diaplay All Members for \MyNamespace\MyApp\Vehicle\Vehicle Array ( [0] => MyNamespace\MyApp\Vehicle\AirVehicle\Rocket\Rocket Object ( [childItem1:MyNamespace\MyApp\Vehicle\AirVehicle\Rocket\Rocket:private] => Rocket c1 [childItem2:MyNamespace\MyApp\Vehicle\AirVehicle\Rocket\Rocket:private] => Rocket c2 [parentItem1:MyNamespace\MyApp\Vehicle\AirVehicle\AirVehicle:private] => Rocket p1 [parentItem2:MyNamespace\MyApp\Vehicle\AirVehicle\AirVehicle:private] => Rocket p2 [id:MyNamespace\MyApp\Vehicle\Vehicle:private] => 1 [grandParentItem1:MyNamespace\MyApp\Vehicle\Vehicle:private] => Rocket g1 [grandParentItem2:MyNamespace\MyApp\Vehicle\Vehicle:private] => Rocket g2 ) [1] => MyNamespace\MyApp\Vehicle\AirVehicle\Airplane\Airplane Object ( [childItem1:MyNamespace\MyApp\Vehicle\AirVehicle\Airplane\Airplane:private] => Airplane c1 [childItem2:MyNamespace\MyApp\Vehicle\AirVehicle\Airplane\Airplane:private] => Airplane c2 [parentItem1:MyNamespace\MyApp\Vehicle\AirVehicle\AirVehicle:private] => Airplane p1 [parentItem2:MyNamespace\MyApp\Vehicle\AirVehicle\AirVehicle:private] => Airplane p2 [id:MyNamespace\MyApp\Vehicle\Vehicle:private] => 2 [grandParentItem1:MyNamespace\MyApp\Vehicle\Vehicle:private] => Airplane g1 [grandParentItem2:MyNamespace\MyApp\Vehicle\Vehicle:private] => Airplane g2 ) [2] => MyNamespace\MyApp\Vehicle\GroundVehicle\Train\Train Object ( [childItem1:MyNamespace\MyApp\Vehicle\GroundVehicle\Train\Train:private] => Train c1 [childItem2:MyNamespace\MyApp\Vehicle\GroundVehicle\Train\Train:private] => Train c2 [parentItem1:MyNamespace\MyApp\Vehicle\GroundVehicle\GroundVehicle:private] => Train p1 [parentItem2:MyNamespace\MyApp\Vehicle\GroundVehicle\GroundVehicle:private] => Train p2 [id:MyNamespace\MyApp\Vehicle\Vehicle:private] => 3 [grandParentItem1:MyNamespace\MyApp\Vehicle\Vehicle:private] => Train g1 [grandParentItem2:MyNamespace\MyApp\Vehicle\Vehicle:private] => Train g2 ) [3] => MyNamespace\MyApp\Vehicle\GroundVehicle\Car\Car Object ( [childItem1:MyNamespace\MyApp\Vehicle\GroundVehicle\Car\Car:private] => Car c1 [childItem2:MyNamespace\MyApp\Vehicle\GroundVehicle\Car\Car:private] => Car c2 [parentItem1:MyNamespace\MyApp\Vehicle\GroundVehicle\GroundVehicle:private] => Car p1 [parentItem2:MyNamespace\MyApp\Vehicle\GroundVehicle\GroundVehicle:private] => Car p2 [id:MyNamespace\MyApp\Vehicle\Vehicle:private] => 4 [grandParentItem1:MyNamespace\MyApp\Vehicle\Vehicle:private] => Car g1 [grandParentItem2:MyNamespace\MyApp\Vehicle\Vehicle:private] => Car g2 ) [4] => MyNamespace\MyApp\Vehicle\AirVehicle\Rocket\Rocket Object ( [childItem1:MyNamespace\MyApp\Vehicle\AirVehicle\Rocket\Rocket:private] => Rocket c1 [childItem2:MyNamespace\MyApp\Vehicle\AirVehicle\Rocket\Rocket:private] => Rocket c2 [parentItem1:MyNamespace\MyApp\Vehicle\AirVehicle\AirVehicle:private] => Rocket p1 [parentItem2:MyNamespace\MyApp\Vehicle\AirVehicle\AirVehicle:private] => Rocket p2 [id:MyNamespace\MyApp\Vehicle\Vehicle:private] => 5 [grandParentItem1:MyNamespace\MyApp\Vehicle\Vehicle:private] => Rocket g1 [grandParentItem2:MyNamespace\MyApp\Vehicle\Vehicle:private] => Rocket g2 ) [5] => MyNamespace\MyApp\Vehicle\AirVehicle\Airplane\Airplane Object ( [childItem1:MyNamespace\MyApp\Vehicle\AirVehicle\Airplane\Airplane:private] => Airplane c1 [childItem2:MyNamespace\MyApp\Vehicle\AirVehicle\Airplane\Airplane:private] => Airplane c2 [parentItem1:MyNamespace\MyApp\Vehicle\AirVehicle\AirVehicle:private] => Airplane p1 [parentItem2:MyNamespace\MyApp\Vehicle\AirVehicle\AirVehicle:private] => Airplane p2 [id:MyNamespace\MyApp\Vehicle\Vehicle:private] => 6 [grandParentItem1:MyNamespace\MyApp\Vehicle\Vehicle:private] => Airplane g1 [grandParentItem2:MyNamespace\MyApp\Vehicle\Vehicle:private] => Airplane g2 ) [6] => MyNamespace\MyApp\Vehicle\GroundVehicle\Train\Train Object ( [childItem1:MyNamespace\MyApp\Vehicle\GroundVehicle\Train\Train:private] => Train c1 [childItem2:MyNamespace\MyApp\Vehicle\GroundVehicle\Train\Train:private] => Train c2 [parentItem1:MyNamespace\MyApp\Vehicle\GroundVehicle\GroundVehicle:private] => Train p1 [parentItem2:MyNamespace\MyApp\Vehicle\GroundVehicle\GroundVehicle:private] => Train p2 [id:MyNamespace\MyApp\Vehicle\Vehicle:private] => 7 [grandParentItem1:MyNamespace\MyApp\Vehicle\Vehicle:private] => Train g1 [grandParentItem2:MyNamespace\MyApp\Vehicle\Vehicle:private] => Train g2 ) [7] => MyNamespace\MyApp\Vehicle\GroundVehicle\Car\Car Object ( [childItem1:MyNamespace\MyApp\Vehicle\GroundVehicle\Car\Car:private] => Car c1 [childItem2:MyNamespace\MyApp\Vehicle\GroundVehicle\Car\Car:private] => Car c2 [parentItem1:MyNamespace\MyApp\Vehicle\GroundVehicle\GroundVehicle:private] => Car p1 [parentItem2:MyNamespace\MyApp\Vehicle\GroundVehicle\GroundVehicle:private] => Car p2 [id:MyNamespace\MyApp\Vehicle\Vehicle:private] => 8 [grandParentItem1:MyNamespace\MyApp\Vehicle\Vehicle:private] => Car g1 [grandParentItem2:MyNamespace\MyApp\Vehicle\Vehicle:private] => Car g2 ) ) Diaplay All Members for \MyNamespace\MyApp\Vehicle\GroundVehicle\GroundVehicle Array ( [0] => MyNamespace\MyApp\Vehicle\GroundVehicle\Train\Train Object ( [childItem1:MyNamespace\MyApp\Vehicle\GroundVehicle\Train\Train:private] => Train c1 [childItem2:MyNamespace\MyApp\Vehicle\GroundVehicle\Train\Train:private] => Train c2 [parentItem1:MyNamespace\MyApp\Vehicle\GroundVehicle\GroundVehicle:private] => Train p1 [parentItem2:MyNamespace\MyApp\Vehicle\GroundVehicle\GroundVehicle:private] => Train p2 [id:MyNamespace\MyApp\Vehicle\Vehicle:private] => 3 [grandParentItem1:MyNamespace\MyApp\Vehicle\Vehicle:private] => Train g1 [grandParentItem2:MyNamespace\MyApp\Vehicle\Vehicle:private] => Train g2 ) [1] => MyNamespace\MyApp\Vehicle\GroundVehicle\Car\Car Object ( [childItem1:MyNamespace\MyApp\Vehicle\GroundVehicle\Car\Car:private] => Car c1 [childItem2:MyNamespace\MyApp\Vehicle\GroundVehicle\Car\Car:private] => Car c2 [parentItem1:MyNamespace\MyApp\Vehicle\GroundVehicle\GroundVehicle:private] => Car p1 [parentItem2:MyNamespace\MyApp\Vehicle\GroundVehicle\GroundVehicle:private] => Car p2 [id:MyNamespace\MyApp\Vehicle\Vehicle:private] => 4 [grandParentItem1:MyNamespace\MyApp\Vehicle\Vehicle:private] => Car g1 [grandParentItem2:MyNamespace\MyApp\Vehicle\Vehicle:private] => Car g2 ) [2] => MyNamespace\MyApp\Vehicle\GroundVehicle\Train\Train Object ( [childItem1:MyNamespace\MyApp\Vehicle\GroundVehicle\Train\Train:private] => Train c1 [childItem2:MyNamespace\MyApp\Vehicle\GroundVehicle\Train\Train:private] => Train c2 [parentItem1:MyNamespace\MyApp\Vehicle\GroundVehicle\GroundVehicle:private] => Train p1 [parentItem2:MyNamespace\MyApp\Vehicle\GroundVehicle\GroundVehicle:private] => Train p2 [id:MyNamespace\MyApp\Vehicle\Vehicle:private] => 7 [grandParentItem1:MyNamespace\MyApp\Vehicle\Vehicle:private] => Train g1 [grandParentItem2:MyNamespace\MyApp\Vehicle\Vehicle:private] => Train g2 ) [3] => MyNamespace\MyApp\Vehicle\GroundVehicle\Car\Car Object ( [childItem1:MyNamespace\MyApp\Vehicle\GroundVehicle\Car\Car:private] => Car c1 [childItem2:MyNamespace\MyApp\Vehicle\GroundVehicle\Car\Car:private] => Car c2 [parentItem1:MyNamespace\MyApp\Vehicle\GroundVehicle\GroundVehicle:private] => Car p1 [parentItem2:MyNamespace\MyApp\Vehicle\GroundVehicle\GroundVehicle:private] => Car p2 [id:MyNamespace\MyApp\Vehicle\Vehicle:private] => 8 [grandParentItem1:MyNamespace\MyApp\Vehicle\Vehicle:private] => Car g1 [grandParentItem2:MyNamespace\MyApp\Vehicle\Vehicle:private] => Car g2 ) ) Diaplay All Members for \MyNamespace\MyApp\Vehicle\AirVehicle\Rocket\Rocket Array ( [0] => MyNamespace\MyApp\Vehicle\AirVehicle\Rocket\Rocket Object ( [childItem1:MyNamespace\MyApp\Vehicle\AirVehicle\Rocket\Rocket:private] => Rocket c1 [childItem2:MyNamespace\MyApp\Vehicle\AirVehicle\Rocket\Rocket:private] => Rocket c2 [parentItem1:MyNamespace\MyApp\Vehicle\AirVehicle\AirVehicle:private] => Rocket p1 [parentItem2:MyNamespace\MyApp\Vehicle\AirVehicle\AirVehicle:private] => Rocket p2 [id:MyNamespace\MyApp\Vehicle\Vehicle:private] => 1 [grandParentItem1:MyNamespace\MyApp\Vehicle\Vehicle:private] => Rocket g1 [grandParentItem2:MyNamespace\MyApp\Vehicle\Vehicle:private] => Rocket g2 ) [1] => MyNamespace\MyApp\Vehicle\AirVehicle\Rocket\Rocket Object ( [childItem1:MyNamespace\MyApp\Vehicle\AirVehicle\Rocket\Rocket:private] => Rocket c1 [childItem2:MyNamespace\MyApp\Vehicle\AirVehicle\Rocket\Rocket:private] => Rocket c2 [parentItem1:MyNamespace\MyApp\Vehicle\AirVehicle\AirVehicle:private] => Rocket p1 [parentItem2:MyNamespace\MyApp\Vehicle\AirVehicle\AirVehicle:private] => Rocket p2 [id:MyNamespace\MyApp\Vehicle\Vehicle:private] => 5 [grandParentItem1:MyNamespace\MyApp\Vehicle\Vehicle:private] => Rocket g1 [grandParentItem2:MyNamespace\MyApp\Vehicle\Vehicle:private] => Rocket g2 ) ) Diaplay All Members for \MyNamespace\MyApp\Vehicle\AirVehicle\Airplane\Airplane Array ( [0] => MyNamespace\MyApp\Vehicle\AirVehicle\Airplane\Airplane Object ( [childItem1:MyNamespace\MyApp\Vehicle\AirVehicle\Airplane\Airplane:private] => Airplane c1 [childItem2:MyNamespace\MyApp\Vehicle\AirVehicle\Airplane\Airplane:private] => Airplane c2 [parentItem1:MyNamespace\MyApp\Vehicle\AirVehicle\AirVehicle:private] => Airplane p1 [parentItem2:MyNamespace\MyApp\Vehicle\AirVehicle\AirVehicle:private] => Airplane p2 [id:MyNamespace\MyApp\Vehicle\Vehicle:private] => 2 [grandParentItem1:MyNamespace\MyApp\Vehicle\Vehicle:private] => Airplane g1 [grandParentItem2:MyNamespace\MyApp\Vehicle\Vehicle:private] => Airplane g2 ) [1] => MyNamespace\MyApp\Vehicle\AirVehicle\Airplane\Airplane Object ( [childItem1:MyNamespace\MyApp\Vehicle\AirVehicle\Airplane\Airplane:private] => Airplane c1 [childItem2:MyNamespace\MyApp\Vehicle\AirVehicle\Airplane\Airplane:private] => Airplane c2 [parentItem1:MyNamespace\MyApp\Vehicle\AirVehicle\AirVehicle:private] => Airplane p1 [parentItem2:MyNamespace\MyApp\Vehicle\AirVehicle\AirVehicle:private] => Airplane p2 [id:MyNamespace\MyApp\Vehicle\Vehicle:private] => 6 [grandParentItem1:MyNamespace\MyApp\Vehicle\Vehicle:private] => Airplane g1 [grandParentItem2:MyNamespace\MyApp\Vehicle\Vehicle:private] => Airplane g2 ) ) Diaplay All Members for \MyNamespace\MyApp\Vehicle\AirVehicle\AirVehicle Array ( [0] => MyNamespace\MyApp\Vehicle\AirVehicle\Rocket\Rocket Object ( [childItem1:MyNamespace\MyApp\Vehicle\AirVehicle\Rocket\Rocket:private] => Rocket c1 [childItem2:MyNamespace\MyApp\Vehicle\AirVehicle\Rocket\Rocket:private] => Rocket c2 [parentItem1:MyNamespace\MyApp\Vehicle\AirVehicle\AirVehicle:private] => Rocket p1 [parentItem2:MyNamespace\MyApp\Vehicle\AirVehicle\AirVehicle:private] => Rocket p2 [id:MyNamespace\MyApp\Vehicle\Vehicle:private] => 1 [grandParentItem1:MyNamespace\MyApp\Vehicle\Vehicle:private] => Rocket g1 [grandParentItem2:MyNamespace\MyApp\Vehicle\Vehicle:private] => Rocket g2 ) [1] => MyNamespace\MyApp\Vehicle\AirVehicle\Airplane\Airplane Object ( [childItem1:MyNamespace\MyApp\Vehicle\AirVehicle\Airplane\Airplane:private] => Airplane c1 [childItem2:MyNamespace\MyApp\Vehicle\AirVehicle\Airplane\Airplane:private] => Airplane c2 [parentItem1:MyNamespace\MyApp\Vehicle\AirVehicle\AirVehicle:private] => Airplane p1 [parentItem2:MyNamespace\MyApp\Vehicle\AirVehicle\AirVehicle:private] => Airplane p2 [id:MyNamespace\MyApp\Vehicle\Vehicle:private] => 2 [grandParentItem1:MyNamespace\MyApp\Vehicle\Vehicle:private] => Airplane g1 [grandParentItem2:MyNamespace\MyApp\Vehicle\Vehicle:private] => Airplane g2 ) [2] => MyNamespace\MyApp\Vehicle\AirVehicle\Rocket\Rocket Object ( [childItem1:MyNamespace\MyApp\Vehicle\AirVehicle\Rocket\Rocket:private] => Rocket c1 [childItem2:MyNamespace\MyApp\Vehicle\AirVehicle\Rocket\Rocket:private] => Rocket c2 [parentItem1:MyNamespace\MyApp\Vehicle\AirVehicle\AirVehicle:private] => Rocket p1 [parentItem2:MyNamespace\MyApp\Vehicle\AirVehicle\AirVehicle:private] => Rocket p2 [id:MyNamespace\MyApp\Vehicle\Vehicle:private] => 5 [grandParentItem1:MyNamespace\MyApp\Vehicle\Vehicle:private] => Rocket g1 [grandParentItem2:MyNamespace\MyApp\Vehicle\Vehicle:private] => Rocket g2 ) [3] => MyNamespace\MyApp\Vehicle\AirVehicle\Airplane\Airplane Object ( [childItem1:MyNamespace\MyApp\Vehicle\AirVehicle\Airplane\Airplane:private] => Airplane c1 [childItem2:MyNamespace\MyApp\Vehicle\AirVehicle\Airplane\Airplane:private] => Airplane c2 [parentItem1:MyNamespace\MyApp\Vehicle\AirVehicle\AirVehicle:private] => Airplane p1 [parentItem2:MyNamespace\MyApp\Vehicle\AirVehicle\AirVehicle:private] => Airplane p2 [id:MyNamespace\MyApp\Vehicle\Vehicle:private] => 6 [grandParentItem1:MyNamespace\MyApp\Vehicle\Vehicle:private] => Airplane g1 [grandParentItem2:MyNamespace\MyApp\Vehicle\Vehicle:private] => Airplane g2 ) ) Diaplay All Members for \MyNamespace\MyApp\Vehicle\GroundVehicle\Train\Train Array ( [0] => MyNamespace\MyApp\Vehicle\GroundVehicle\Train\Train Object ( [childItem1:MyNamespace\MyApp\Vehicle\GroundVehicle\Train\Train:private] => Train c1 [childItem2:MyNamespace\MyApp\Vehicle\GroundVehicle\Train\Train:private] => Train c2 [parentItem1:MyNamespace\MyApp\Vehicle\GroundVehicle\GroundVehicle:private] => Train p1 [parentItem2:MyNamespace\MyApp\Vehicle\GroundVehicle\GroundVehicle:private] => Train p2 [id:MyNamespace\MyApp\Vehicle\Vehicle:private] => 3 [grandParentItem1:MyNamespace\MyApp\Vehicle\Vehicle:private] => Train g1 [grandParentItem2:MyNamespace\MyApp\Vehicle\Vehicle:private] => Train g2 ) [1] => MyNamespace\MyApp\Vehicle\GroundVehicle\Train\Train Object ( [childItem1:MyNamespace\MyApp\Vehicle\GroundVehicle\Train\Train:private] => Train c1 [childItem2:MyNamespace\MyApp\Vehicle\GroundVehicle\Train\Train:private] => Train c2 [parentItem1:MyNamespace\MyApp\Vehicle\GroundVehicle\GroundVehicle:private] => Train p1 [parentItem2:MyNamespace\MyApp\Vehicle\GroundVehicle\GroundVehicle:private] => Train p2 [id:MyNamespace\MyApp\Vehicle\Vehicle:private] => 7 [grandParentItem1:MyNamespace\MyApp\Vehicle\Vehicle:private] => Train g1 [grandParentItem2:MyNamespace\MyApp\Vehicle\Vehicle:private] => Train g2 ) ) Diaplay All Members for \MyNamespace\MyApp\Vehicle\GroundVehicle\Car\Car Array ( [0] => MyNamespace\MyApp\Vehicle\GroundVehicle\Car\Car Object ( [childItem1:MyNamespace\MyApp\Vehicle\GroundVehicle\Car\Car:private] => Car c1 [childItem2:MyNamespace\MyApp\Vehicle\GroundVehicle\Car\Car:private] => Car c2 [parentItem1:MyNamespace\MyApp\Vehicle\GroundVehicle\GroundVehicle:private] => Car p1 [parentItem2:MyNamespace\MyApp\Vehicle\GroundVehicle\GroundVehicle:private] => Car p2 [id:MyNamespace\MyApp\Vehicle\Vehicle:private] => 4 [grandParentItem1:MyNamespace\MyApp\Vehicle\Vehicle:private] => Car g1 [grandParentItem2:MyNamespace\MyApp\Vehicle\Vehicle:private] => Car g2 ) [1] => MyNamespace\MyApp\Vehicle\GroundVehicle\Car\Car Object ( [childItem1:MyNamespace\MyApp\Vehicle\GroundVehicle\Car\Car:private] => Car c1 [childItem2:MyNamespace\MyApp\Vehicle\GroundVehicle\Car\Car:private] => Car c2 [parentItem1:MyNamespace\MyApp\Vehicle\GroundVehicle\GroundVehicle:private] => Car p1 [parentItem2:MyNamespace\MyApp\Vehicle\GroundVehicle\GroundVehicle:private] => Car p2 [id:MyNamespace\MyApp\Vehicle\Vehicle:private] => 8 [grandParentItem1:MyNamespace\MyApp\Vehicle\Vehicle:private] => Car g1 [grandParentItem2:MyNamespace\MyApp\Vehicle\Vehicle:private] => Car g2 ) ) -
Doctrine, Composer, and namespace
NotionCommotion replied to NotionCommotion's topic in PHP Coding Help
@benanamen, I am building a web interface to manage various industrial integration gateways. Some act as servers and others act as clients. Some utilize ethernet and others utilize rs-485 serial communication. Typical protocols include modbus, devicenet, bacnet, lonworks, profibus, etc. To implement this, I am creating an object (with injected other objects) for each which fulfills the required functionality. There are some portions where inheritance is well fit and I wish to extend classes. Current implementation uses a mapper class to pull the various properties from the db which are injected into an entity object. Everything is vanilla PHP without some 3rd party framework and it works as desired, but is becoming more and more difficult to manage, and I feel that maybe I should be using some dedicated orm. Maybe I shouldn't be using an orm (and if so, whether it should be doctrine), but the only way I know how to confirm this is to personally try it out and create new entities, retrieve one by its ID, retrieve a set of them, modify them, etc. And while I can do this initially for the entire application, it is much simpler to do so for a mock application of vehicles, rockets, etc. So... assuming this is just an academic exercise to create a Rocket that is inherited from a Vehicle, does my entity meta data look reasonable? Do you know why I am unable to retrieve an entity by ID or retrieve a group of entities? Thanks -
Doctrine, Composer, and namespace
NotionCommotion replied to NotionCommotion's topic in PHP Coding Help
I appreciate your passion to abolishing all xy problems, however, I am not asking for you to build something for me but for you to teach me something. Specifically, how to implement Class Table Inheritance using Doctrine. -
Doctrine, Composer, and namespace
NotionCommotion replied to NotionCommotion's topic in PHP Coding Help
Below is some sample data. SELECT *, 'airplane' FROM vehicle_table vt INNER JOIN air_vehicle av ON av.id=vt.id INNER JOIN airplane_table ap ON ap.id=av.id WHERE vt.id>=32 AND vt.id<=42 UNION SELECT *, 'rocket' FROM vehicle_table vt INNER JOIN air_vehicle av ON av.id=vt.id INNER JOIN rocket_table rt ON rt.id=av.id WHERE vt.id>=32 AND vt.id<=42 UNION SELECT *, 'car' FROM vehicle_table vt INNER JOIN ground_vehicle gv ON gv.id=vt.id INNER JOIN car_table ct ON ct.id=gv.id WHERE vt.id>=32 AND vt.id<=42 UNION SELECT *, 'train' FROM vehicle_table vt INNER JOIN ground_vehicle gv ON gv.id=vt.id INNER JOIN train_table tt ON tt.id=gv.id WHERE vt.id>=32 AND vt.id<=42; id grandParentItem1 grandParentItem2 discriminator_column id parentItem1 parentItem2 id childItem1 childItem2 type 32 Airplane g1 Airplane g2 airplane 32 Airplane p1 Airplane p2 32 Airplane c1 Airplane c2 airplane 36 Airplane g1 Airplane g2 airplane 36 Airplane p1 Airplane p2 36 Airplane c1 Airplane c2 airplane 40 Airplane g1 Airplane g2 airplane 40 Airplane p1 Airplane p2 40 Airplane c1 Airplane c2 airplane 35 Rocket g1 Rocket g2 rocket 35 Rocket p1 Rocket p2 35 Rocket c1 Rocket c2 rocket 39 Rocket g1 Rocket g2 rocket 39 Rocket p1 Rocket p2 39 Rocket c1 Rocket c2 rocket 34 Car g1 Car g2 car 34 Car p1 Car p2 34 Car c1 Car c2 car 38 Car g1 Car g2 car 38 Car p1 Car p2 38 Car c1 Car c2 car 42 Car g1 Car g2 car 42 Car p1 Car p2 42 Car c1 Car c2 car 33 Train g1 Train g2 train 33 Train p1 Train p2 33 Train c1 Train c2 train 37 Train g1 Train g2 train 37 Train p1 Train p2 37 Train c1 Train c2 train 41 Train g1 Train g2 train 41 Train p1 Train p2 41 Train c1 Train c2 train