{"id":2489,"date":"2017-11-28T11:09:29","date_gmt":"2017-11-28T10:09:29","guid":{"rendered":"https:\/\/www.clickstorm.de\/blog\/?p=2489"},"modified":"2019-09-26T16:47:21","modified_gmt":"2019-09-26T14:47:21","slug":"doctrine-dbal-typo3-version-8","status":"publish","type":"post","link":"https:\/\/www.clickstorm.de\/blog\/doctrine-dbal-typo3-version-8\/","title":{"rendered":"Doctrine DBAL ab TYPO3 Version 8 nutzen"},"content":{"rendered":"<p>Mit der TYPO3 Version 8 wurde mit Doctrine eine Datenbankabstraktionsschicht in das System integriert. Alle bisherigen Datenbankaufrufe im Core wurden entsprechend konventiert. Nun sind die Extension-Entwickler dran, die Technologie zu nutzen. Dabei sollte man sich nicht abschrecken lassen. Die neuen Funktionen sind bei unseren Symfony-Entwicklern bereits bekannt und leicht zu erlernen.<\/p>\n<p>Unser erster Blog-Beitrag zur Weihnachtszeit ist ein kleines Geschenk f\u00fcr TYPO3-Entwickler. Kurz vor der Ver\u00f6ffentlichung von TYPO3 9.0 geben wir Ihnen einen Einblick in Doctrine mit allerhand Beispielen.<\/p>\n<h2>Was ist Doctrine?<\/h2>\n<p>Das Doctrine\u00a0<a href=\"http:\/\/www.doctrine-project.org\/\" target=\"_blank\" rel=\"noopener noreferrer\">Projekt<\/a> beinhaltet verschiedene PHP-Bibliotheken, deren prim\u00e4rer Fokus auf Datenbanken und Objekt-Mapping liegt. Zu den Kernprojekten geh\u00f6ren der Object Relational Mapper (ORM) und der Database Abstraction Layer (DBAL, deutsch: Datenbankabstraktionsschicht).<\/p>\n<p>Einfach gesagt dient Doctrine dazu eine Ebene zwischen PHP und Datenbank zu schaffen. Der Einsatz dieser Ebene erm\u00f6glicht es mit ein und denselben PHP-Aufrufen unterschiedliche Datenbankmanagementsysteme (DBMS) anzusprechen. Zu diesen Systemen geh\u00f6ren derzeit u.a. MySQL, Oracle, PostgreSQL und Microsoft SQL Server. Dadurch ist die PHP-Anwendung und deren Entwickler weitestgehend unabh\u00e4ngig von dem System der Datenbank.<\/p>\n<p>Weitere Vorteile von Doctrine sind laut der eigenen Webseite:<\/p>\n<ul>\n<li>entwickelt seit 2006, mit einer sehr stabilen und hoch qualitativen Codebasis<\/li>\n<li>sehr flexibles und m\u00e4chtiges Objekt-Mapping und Abfrage-Funktionen<\/li>\n<li>gro\u00dfe Community und Integration in viele verschiedene Frameworks,\u00a0 u.a. Symfony und Zend Framework<\/li>\n<\/ul>\n<p>Doch wie wurde Doctrine in TYPO3 integriert? Das beleuchten wir im n\u00e4chsten Abschnitt.<\/p>\n<h2>Doctrine und TYPO3<\/h2>\n<p>Eine Datenbankabstraktionsschicht ist in TYPO3 kein neues Anliegen. Bisher gab es die Erweiterungen <em>dbal<\/em> und\u00a0<em>adodb<\/em>, welche Teil des TYPO3-Kerns waren. Allerdings mussten sie erst bei bedarf aktiviert werden. Standardm\u00e4\u00dfig wurde TYPO3 mit MySQL betrieben. Durch die Erweiterungen war es m\u00f6glich weitere DBMS zu nutzen. Nun soll daf\u00fcr Doctrine zum Einsatz kommen. Deswegen wurden die <em>dbal<\/em> und <em>adodb<\/em> aus dem Kern entfernt. Wer sie dennoch ben\u00f6tigt, kann sie im <a href=\"https:\/\/extensions.typo3.org\/\" target=\"_blank\" rel=\"noopener noreferrer\">TYPO3 Extension Repository (TER)<\/a> herunterladen und installieren.<\/p>\n<p>Nun aber zur\u00fcck aus der Vergangenheit hinein in die Zukunft. Ein wesentliches Feature der TYPO3 Version 8.7 LTS ist die Nutzung von Doctrine. Dazu wurden bis Version 8.4 alle Datenbankzugriffe im Kern umgeschrieben. Am einfachsten lassen sich die dazugeh\u00f6rigen \u00c4nderungen anhand von Praxisbeispielen zeigen.<\/p>\n<h2>Praxisbeispiele und CodeSnippets<\/h2>\n<p>Bisher wurden Datenbankzugriffe \u00fcber die Variable $GLOBALS[&#8218;TYPO3_DB&#8216;] abgelbildet. Diese ist eine Instanz der PHP-Klasse\u00a0DatabaseConnection. Diese Klasse existiert weiterhin in TYPO3 Version 8, wird allerdings in TYPO3 Version 9 entfernt. Somit wird ein Umstieg auf Doctrine f\u00fcr Entwickler unausweichlich.<\/p>\n<p>Doch kein Grund zur Panik. Wer in einem Extbase-Repository bereits eine Abfrage implementiert hat, wird sich an die neue Syntax schnell gew\u00f6hnen.<\/p>\n<p>Die wichtigsten Klassen im Umgang mit Doctrine in TYPO3 hei\u00dfen ConnectionPool und\u00a0QueryBuilder. Die erste wird dazu genutzt, um eine Verbindung zu einer Tabelle aufzubauen oder einen QueryBuilder zu instanzieren. Dieser wiederrum dient dazu komplexe Abfragen aufzubauen.<\/p>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"php\">use TYPO3\\CMS\\Core\\Database\\ConnectionPool;\r\nuse TYPO3\\CMS\\Core\\Database\\Query\\QueryBuilder;\r\nuse TYPO3\\CMS\\Core\\Utility\\GeneralUtility;\r\n\r\n\/\/\u00a0Query Builder f\u00fcr eine Tabelle instanzieren\r\n$queryBuilder\u00a0=\u00a0GeneralUtility::makeInstance(ConnectionPool::class)\r\n                  -&gt;getQueryBuilderForTable('tt_content');\r\n\r\n\/\/\u00a0oder eine Verbindung aufbauen\r\n$connection\u00a0=\u00a0GeneralUtility::makeInstance(ConnectionPool::class)\r\n                -&gt;getConnectionForTable('tt_content');<\/pre>\n<p>Eine Verbindung kann f\u00fcr kleine Abfragen genutzt werden, der QueryBuilder f\u00fcr komplexe. In der Praxis sieht das dann wie folgt aus.<\/p>\n<h3>Select &#8211; Abfrage von Datens\u00e4tzen<\/h3>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"php\">\/** @var QueryBuilder $queryBuilder *\/\r\n$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)\r\n  -&gt;getQueryBuilderForTable($table);\r\n\r\n$limit = 4;\r\n$offset = 0;\r\n\r\n$data = $queryBuilder\r\n -&gt;select('*')\r\n -&gt;from($table)\r\n -&gt;where($queryBuilder-&gt;expr()-&gt;eq('deleted', 0))\r\n -&gt;orWhere(\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0$queryBuilder-&gt;expr()-&gt;like(\r\n        'teaser', \r\n        '%' . $queryBuilder-&gt;escapeLikeWildcards($search) . '%'\r\n      ),\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0$queryBuilder-&gt;expr()-&gt;like(\r\n        'bodytext', \r\n        '%' . $queryBuilder-&gt;escapeLikeWildcards($search) . '%'\r\n      )\r\n\u00a0\u00a0\u00a0)\r\n -&gt;andWhere(\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0$queryBuilder-&gt;expr()-&gt;eq(\r\n        'pid',\u00a0\r\n        $queryBuilder-&gt;createNamedParameter($pid, \\PDO::PARAM_INT)\r\n      )\r\n\u00a0\u00a0\u00a0)\r\n -&gt;orderBy('date', 'DESC')-&gt;addOrderBy('title')\r\n -&gt;groupBy('author')\r\n -&gt;setFirstResult($offset)\r\n -&gt;setMaxResults($limit)\r\n -&gt;execute()\r\n -&gt;fetchAll();<\/pre>\n<p>Hier sehen Sie bereits ein relativ komplexes Beispiel einer Select-Abfrage. Allerdings l\u00e4sst es sich einfach lesen. Bei einigen Ausdr\u00fccken, wie\u00a0<code class=\"EnlighterJSRAW\" data-enlighter-language=\"php\">-&gt;where()<\/code> und <code class=\"EnlighterJSRAW\" data-enlighter-language=\"php\">-&gt;orderBy()<\/code> ist darauf zu achten, dass sie nur einmal pro Abfrage verwendet werden sollten. Noch wichtiger ist, alle Ausdr\u00fccke abzusichern. Weiter unten im Text erfahren Sie mehr dazu.<\/p>\n<p>Mit <code class=\"EnlighterJSRAW\" data-enlighter-language=\"php\">-&gt;execute()<\/code> erhalten Sie ein Statement-Objekt zur\u00fcck. Mit einer <code class=\"EnlighterJSRAW\" data-enlighter-language=\"php\">-&gt;fetch()<\/code> Schleife lassen sich die einzelnen Zeilen abfragen oder Sie nutzen direkt <code class=\"EnlighterJSRAW\" data-enlighter-language=\"php\">-&gt;fetchAll()<\/code> um ein Array mit allen Eintr\u00e4gen zu erhalten.<\/p>\n<h3>Join &#8211; Tabellen miteinander verkn\u00fcpfen<\/h3>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"php\">\/** @var QueryBuilder $queryBuilder *\/\r\n$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)\r\n  -&gt;getQueryBuilderForTable($table);\r\n\r\n$table = 'tt_content';\r\n$joinTable = 'sys_category_record_mm';\r\n\r\n$statement = $queryBuilder\r\n\u00a0\u00a0\u00a0-&gt;select('*')\r\n\u00a0\u00a0\u00a0-&gt;from($table)\r\n\u00a0\u00a0\u00a0-&gt;leftJoin(\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0$table,\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0$joinTable,\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0'categoryMM',\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0$queryBuilder-&gt;expr()-&gt;eq(\r\n        'categoryMM.uid_foreign',\u00a0\r\n        $queryBuilder-&gt;quoteIdentifier('tt_content.uid')\r\n      )\r\n\u00a0\u00a0\u00a0)\r\n\u00a0\u00a0\u00a0-&gt;where(\r\n\u00a0\u00a0\u00a0\u00a0\u00a0\u00a0$queryBuilder-&gt;expr()-&gt;eq('categoryMM.tablenames', \r\n         $queryBuilder-&gt;createNamedParameter($table)),\r\n      $queryBuilder-&gt;expr()-&gt;eq('categoryMM.fieldname', \r\n         $queryBuilder-&gt;createNamedParameter('categories')),\r\n      $queryBuilder-&gt;expr()-&gt;eq(\r\n        'categoryMM.uid', \r\n        $queryBuilder-&gt;createNamedParameter(42, \\PDO::PARAM_INT)\r\n      )\r\n\u00a0\u00a0\u00a0)\r\n\u00a0\u00a0\u00a0-&gt;execute();<\/pre>\n<p>Alle m\u00f6glichen Ausdr\u00fccke f\u00fcr die Verkn\u00fcpfung von Tabellen lauten: <code class=\"EnlighterJSRAW\" data-enlighter-language=\"php\">-&gt;join()<\/code>, <code class=\"EnlighterJSRAW\" data-enlighter-language=\"php\">-&gt;innerJoin()<\/code>, <code class=\"EnlighterJSRAW\" data-enlighter-language=\"php\">-&gt;rightJoin()<\/code> und <code class=\"EnlighterJSRAW\" data-enlighter-language=\"php\">-&gt;leftJoin()<\/code>.<\/p>\n<h3>Count &#8211; Anzahl von Datens\u00e4tzen erfragen<\/h3>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"php\">\/** @var QueryBuilder $queryBuilder *\/\r\n$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)\r\n  -&gt;getQueryBuilderForTable($table);\r\n$count = $queryBuilder\r\n -&gt;count('uid')\r\n -&gt;from($table)\r\n -&gt;execute()\r\n -&gt;fetchColumn(0);<\/pre>\n<h3>Insert &#8211; Neue Datens\u00e4tze einf\u00fcgen<\/h3>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"php\">\/** @var QueryBuilder $queryBuilder *\/\r\n$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)\r\n  -&gt;getQueryBuilderForTable($table);\r\n\r\n$arrayNewData = ['title' =&gt; 'Neuer Datensatz', 'tx_csseo_no_index' =&gt; 1];\r\n\r\n$queryBuilder\r\n  -&gt;insert($table)\r\n  -&gt;values($arrayNewData)\r\n  -&gt;execute();<\/pre>\n<h3>Bulk Insert \/ Insert multiple rows<\/h3>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"php\">\/** @var Connection $databaseConnection *\/\r\n$databaseConnection = GeneralUtility::makeInstance(ConnectionPool::class)\r\n  -&gt;getConnectionForTable($table);\r\n\r\n$arrayWithNewData = [['title' =&gt; 'TYPO3'], ['title' =&gt; 'clickstorm GmbH']];\r\n$arrayWithColNames = ['title'];\r\n\r\n\r\n$databaseConnection-&gt;bulkInsert(\r\n $table,\r\n $arrayWithNewData,\r\n $arrayWithColNames\r\n);<\/pre>\n<h3>Update &#8211; Aktualisieren von Datens\u00e4tzen<\/h3>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"php\">\/**\u00a0@var\u00a0Connection\u00a0$databaseConnection\u00a0*\/\r\n$databaseConnection\u00a0=\u00a0GeneralUtility::makeInstance(ConnectionPool::class)\r\n  -&gt;getConnectionForTable($table);\u00a0\r\n\r\n$arrayUpdateData = ['deleted' =&gt; 1];\r\n$arrayWhere = ['uid'\u00a0=&gt;\u00a0'IN\u00a0('\u00a0.\u00a0implode(',',\u00a0$currentIds)\u00a0.\u00a0')'];\r\n\r\n$databaseConnection-&gt;update(\r\n $table,\r\n $arrayUpdateData,\r\n $arrayWhere\r\n);<\/pre>\n<h3>Delete &#8211; L\u00f6schen von Datens\u00e4tzen<\/h3>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"php\">\/** @var Connection $databaseConnection *\/\r\n$databaseConnection = GeneralUtility::makeInstance(ConnectionPool::class)\r\n  -&gt;getConnectionForTable($table);\r\n\r\n$arrayWhere = ['hidden'\u00a0=&gt;\u00a01];\r\n\r\n$databaseConnection-&gt;delete($table, $arrayWhere);<\/pre>\n<h2>Doctrines wichtige Helferfunktionen<\/h2>\n<h3>Absichern von Nutzer-Eingaben mit createNamedParameter()<\/h3>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"php\">-&gt;where(\r\n\u00a0\u00a0\u00a0$queryBuilder-&gt;expr()-&gt;eq('bodytext',\u00a0$queryBuilder-&gt;createNamedParameter($search))\r\n)<\/pre>\n<p><strong>Jede Eingabe<\/strong>, egal woher sie kommt ist mit createNamedParameter abzusichern! Dar\u00fcberhinaus ist darauf zu achten, dass bei <code class=\"EnlighterJSRAW\" data-enlighter-language=\"php\">-&gt;expr()<\/code> <strong>immer<\/strong> das zweite Argument mit <code class=\"EnlighterJSRAW\" data-enlighter-language=\"php\">-&gt;createNamedParameter()<\/code> oder <code class=\"EnlighterJSRAW\" data-enlighter-language=\"php\">-&gt;quoteIdentifier()<\/code>\u00a0 versehen wird. Doctrine selbst \u00fcbernimmt nur die Vermeidung von <a href=\"http:\/\/php.net\/manual\/de\/security.database.sql-injection.php\" target=\"_blank\" rel=\"noopener noreferrer\">SQL-Injections<\/a> bei <code class=\"EnlighterJSRAW\" data-enlighter-language=\"php\">-&gt;setFirstResult()<\/code>\u00a0und <code class=\"EnlighterJSRAW\" data-enlighter-language=\"php\">-&gt;setMaxResults()<\/code>.<\/p>\n<h3>escapeLikeWildcards()<\/h3>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"php\">-&gt;where(\r\n  $queryBuilder-&gt;expr()-&gt;like(\r\n   'bodytext',\r\n   $queryBuilder-&gt;createNamedParameter('%'\u00a0.\u00a0$queryBuilder-&gt;escapeLikeWildcards($search)\u00a0.\u00a0'%')\r\n)\r\n<\/pre>\n<p>Wie diese Funktion bereits durch ihren Namen verr\u00e4t, dient sie dazu m\u00f6gliche Platzhalter, welche bei einer Like-Abfrage genutzt werden k\u00f6nnen, entsprechend abzufangen.<\/p>\n<h3>Debug mit getSQL()<\/h3>\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"php\">\/** @var QueryBuilder $queryBuilder *\/\r\n$queryBuilder = GeneralUtility::makeInstance(ConnectionPool::class)\r\n  -&gt;getQueryBuilderForTable($table);\r\n\r\n$queryBuilder-&gt;select('*')-&gt;from($table);\r\n\r\n\\TYPO3\\CMS\\Extbase\\Utility\\DebuggerUtility::var_dump($queryBuilder-&gt;getSQL());\r\n\r\n$statement\u00a0=\u00a0$queryBuilder-&gt;execute();<\/pre>\n<p>Analog dazu kann die Methode getParameters() genutzt werden. Mit ihr erf\u00e4hrt der Entwickler, mit welchen Werten die Platzhalter in den Statements belegt werden.<\/p>\n<h2>Ausblick<\/h2>\n<p>Weitere ausf\u00fchrliche Beispiele finden Sie in der <a href=\"https:\/\/docs.typo3.org\/typo3cms\/CoreApiReference\/ApiOverview\/Database\/Index.html\" target=\"_blank\" rel=\"noopener noreferrer\">TYPO3-Dokumentation<\/a>. Wir hoffen, dass wir Ihnen einen soliden Einblick in Doctrine geben konnten. Unsere eigenen Extensions wie die <a href=\"https:\/\/www.clickstorm.de\/blog\/onpage-analyse-in-typo3-mit-cs_seo\/\">cs_seo<\/a> oder <a href=\"https:\/\/www.clickstorm.de\/blog\/typo3-erweiterung-cs_youtube_data\/\">cs_youtube_data<\/a> werden wir zeitnah an die TYPO3 Version 9 anpassen. Sollten Sie Anregungen oder Fragen zum Thema haben, hinterlassen Sie gerne einen Kommentar oder nehmen Sie <a href=\"https:\/\/www.clickstorm.de\/kontakt\/\" target=\"_blank\" rel=\"noopener noreferrer\">Kontakt<\/a> mit uns auf.<\/p>\n","protected":false},"excerpt":{"rendered":"<p>Die Zukunft der Datenbankaufraufe in TYPO3<\/p>\n","protected":false},"author":7,"featured_media":2652,"comment_status":"open","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"_acf_changed":false,"footnotes":""},"categories":[135],"tags":[23,142,45,98,9],"class_list":["post-2489","post","type-post","status-publish","format-standard","has-post-thumbnail","hentry","category-cms","tag-cms","tag-datenbank","tag-entwicklung","tag-php","tag-typo3"],"acf":[],"yoast_head":"<!-- This site is optimized with the Yoast SEO plugin v27.9 - https:\/\/yoast.com\/product\/yoast-seo-wordpress\/ -->\n<title>Doctrine DBAL ab TYPO3 Version 8 nutzen - clickstorm Blog<\/title>\n<meta name=\"description\" content=\"Mit der TYPO3 Version 8 wurde mit Doctrine eine Datenbankabstraktionsschicht integriert. Anhand von Codesnippets veranschaulichen wir Ihnen die Neuerungen.\" \/>\n<meta name=\"robots\" content=\"index, follow, max-snippet:-1, max-image-preview:large, max-video-preview:-1\" \/>\n<link rel=\"canonical\" href=\"https:\/\/www.clickstorm.de\/blog\/doctrine-dbal-typo3-version-8\/\" \/>\n<meta property=\"og:locale\" content=\"de_DE\" \/>\n<meta property=\"og:type\" content=\"article\" \/>\n<meta property=\"og:title\" content=\"Doctrine DBAL ab TYPO3 Version 8 nutzen - clickstorm Blog\" \/>\n<meta property=\"og:description\" content=\"Mit der TYPO3 Version 8 wurde mit Doctrine eine Datenbankabstraktionsschicht integriert. Anhand von Codesnippets veranschaulichen wir Ihnen die Neuerungen.\" \/>\n<meta property=\"og:url\" content=\"https:\/\/www.clickstorm.de\/blog\/doctrine-dbal-typo3-version-8\/\" \/>\n<meta property=\"og:site_name\" content=\"clickstorm Blog\" \/>\n<meta property=\"article:publisher\" content=\"https:\/\/de-de.facebook.com\/clickstorm\/\" \/>\n<meta property=\"article:published_time\" content=\"2017-11-28T10:09:29+00:00\" \/>\n<meta property=\"article:modified_time\" content=\"2019-09-26T14:47:21+00:00\" \/>\n<meta property=\"og:image\" content=\"https:\/\/www.clickstorm.de\/blog\/wp-content\/uploads\/2017\/10\/fotolia_68079312.jpg\" \/>\n\t<meta property=\"og:image:width\" content=\"1170\" \/>\n\t<meta property=\"og:image:height\" content=\"780\" \/>\n\t<meta property=\"og:image:type\" content=\"image\/jpeg\" \/>\n<meta name=\"author\" content=\"Marc\" \/>\n<meta name=\"twitter:card\" content=\"summary_large_image\" \/>\n<meta name=\"twitter:creator\" content=\"@clickstorm_gmbh\" \/>\n<meta name=\"twitter:site\" content=\"@clickstorm_gmbh\" \/>\n<meta name=\"twitter:label1\" content=\"Verfasst von\" \/>\n\t<meta name=\"twitter:data1\" content=\"Marc\" \/>\n\t<meta name=\"twitter:label2\" content=\"Gesch\u00e4tzte Lesezeit\" \/>\n\t<meta name=\"twitter:data2\" content=\"6\u00a0Minuten\" \/>\n<script type=\"application\/ld+json\" class=\"yoast-schema-graph\">{\"@context\":\"https:\\\/\\\/schema.org\",\"@graph\":[{\"@type\":\"Article\",\"@id\":\"https:\\\/\\\/www.clickstorm.de\\\/blog\\\/doctrine-dbal-typo3-version-8\\\/#article\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.clickstorm.de\\\/blog\\\/doctrine-dbal-typo3-version-8\\\/\"},\"author\":{\"name\":\"Marc\",\"@id\":\"https:\\\/\\\/www.clickstorm.de\\\/blog\\\/#\\\/schema\\\/person\\\/594fb824a2f049d33b2a1b4406bfc86b\"},\"headline\":\"Doctrine DBAL ab TYPO3 Version 8 nutzen\",\"datePublished\":\"2017-11-28T10:09:29+00:00\",\"dateModified\":\"2019-09-26T14:47:21+00:00\",\"mainEntityOfPage\":{\"@id\":\"https:\\\/\\\/www.clickstorm.de\\\/blog\\\/doctrine-dbal-typo3-version-8\\\/\"},\"wordCount\":789,\"commentCount\":10,\"publisher\":{\"@id\":\"https:\\\/\\\/www.clickstorm.de\\\/blog\\\/#organization\"},\"image\":{\"@id\":\"https:\\\/\\\/www.clickstorm.de\\\/blog\\\/doctrine-dbal-typo3-version-8\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.clickstorm.de\\\/blog\\\/wp-content\\\/uploads\\\/2017\\\/10\\\/fotolia_68079312.jpg\",\"keywords\":[\"CMS\",\"Datenbank\",\"Entwicklung\",\"PHP\",\"TYPO3\"],\"articleSection\":[\"CMS\"],\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"CommentAction\",\"name\":\"Comment\",\"target\":[\"https:\\\/\\\/www.clickstorm.de\\\/blog\\\/doctrine-dbal-typo3-version-8\\\/#respond\"]}]},{\"@type\":\"WebPage\",\"@id\":\"https:\\\/\\\/www.clickstorm.de\\\/blog\\\/doctrine-dbal-typo3-version-8\\\/\",\"url\":\"https:\\\/\\\/www.clickstorm.de\\\/blog\\\/doctrine-dbal-typo3-version-8\\\/\",\"name\":\"Doctrine DBAL ab TYPO3 Version 8 nutzen - clickstorm Blog\",\"isPartOf\":{\"@id\":\"https:\\\/\\\/www.clickstorm.de\\\/blog\\\/#website\"},\"primaryImageOfPage\":{\"@id\":\"https:\\\/\\\/www.clickstorm.de\\\/blog\\\/doctrine-dbal-typo3-version-8\\\/#primaryimage\"},\"image\":{\"@id\":\"https:\\\/\\\/www.clickstorm.de\\\/blog\\\/doctrine-dbal-typo3-version-8\\\/#primaryimage\"},\"thumbnailUrl\":\"https:\\\/\\\/www.clickstorm.de\\\/blog\\\/wp-content\\\/uploads\\\/2017\\\/10\\\/fotolia_68079312.jpg\",\"datePublished\":\"2017-11-28T10:09:29+00:00\",\"dateModified\":\"2019-09-26T14:47:21+00:00\",\"description\":\"Mit der TYPO3 Version 8 wurde mit Doctrine eine Datenbankabstraktionsschicht integriert. Anhand von Codesnippets veranschaulichen wir Ihnen die Neuerungen.\",\"breadcrumb\":{\"@id\":\"https:\\\/\\\/www.clickstorm.de\\\/blog\\\/doctrine-dbal-typo3-version-8\\\/#breadcrumb\"},\"inLanguage\":\"de\",\"potentialAction\":[{\"@type\":\"ReadAction\",\"target\":[\"https:\\\/\\\/www.clickstorm.de\\\/blog\\\/doctrine-dbal-typo3-version-8\\\/\"]}]},{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/www.clickstorm.de\\\/blog\\\/doctrine-dbal-typo3-version-8\\\/#primaryimage\",\"url\":\"https:\\\/\\\/www.clickstorm.de\\\/blog\\\/wp-content\\\/uploads\\\/2017\\\/10\\\/fotolia_68079312.jpg\",\"contentUrl\":\"https:\\\/\\\/www.clickstorm.de\\\/blog\\\/wp-content\\\/uploads\\\/2017\\\/10\\\/fotolia_68079312.jpg\",\"width\":1170,\"height\":780,\"caption\":\"Frau mit Fernglas und Weihnachtsm\u00fctze\"},{\"@type\":\"BreadcrumbList\",\"@id\":\"https:\\\/\\\/www.clickstorm.de\\\/blog\\\/doctrine-dbal-typo3-version-8\\\/#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Home\",\"item\":\"https:\\\/\\\/www.clickstorm.de\\\/blog\\\/\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Doctrine DBAL ab TYPO3 Version 8 nutzen\"}]},{\"@type\":\"WebSite\",\"@id\":\"https:\\\/\\\/www.clickstorm.de\\\/blog\\\/#website\",\"url\":\"https:\\\/\\\/www.clickstorm.de\\\/blog\\\/\",\"name\":\"clickstorm Blog\",\"description\":\"Neuigkeiten rund um Webentwicklung\",\"publisher\":{\"@id\":\"https:\\\/\\\/www.clickstorm.de\\\/blog\\\/#organization\"},\"potentialAction\":[{\"@type\":\"SearchAction\",\"target\":{\"@type\":\"EntryPoint\",\"urlTemplate\":\"https:\\\/\\\/www.clickstorm.de\\\/blog\\\/?s={search_term_string}\"},\"query-input\":{\"@type\":\"PropertyValueSpecification\",\"valueRequired\":true,\"valueName\":\"search_term_string\"}}],\"inLanguage\":\"de\"},{\"@type\":\"Organization\",\"@id\":\"https:\\\/\\\/www.clickstorm.de\\\/blog\\\/#organization\",\"name\":\"clickstorm GmbH\",\"url\":\"https:\\\/\\\/www.clickstorm.de\\\/blog\\\/\",\"logo\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/www.clickstorm.de\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\",\"url\":\"https:\\\/\\\/www.clickstorm.de\\\/blog\\\/wp-content\\\/uploads\\\/2017\\\/11\\\/logo.svg\",\"contentUrl\":\"https:\\\/\\\/www.clickstorm.de\\\/blog\\\/wp-content\\\/uploads\\\/2017\\\/11\\\/logo.svg\",\"caption\":\"clickstorm GmbH\"},\"image\":{\"@id\":\"https:\\\/\\\/www.clickstorm.de\\\/blog\\\/#\\\/schema\\\/logo\\\/image\\\/\"},\"sameAs\":[\"https:\\\/\\\/de-de.facebook.com\\\/clickstorm\\\/\",\"https:\\\/\\\/x.com\\\/clickstorm_gmbh\",\"https:\\\/\\\/www.youtube.com\\\/channel\\\/UCEaU1eUbug6OiI4uU6vA-cA\"]},{\"@type\":\"Person\",\"@id\":\"https:\\\/\\\/www.clickstorm.de\\\/blog\\\/#\\\/schema\\\/person\\\/594fb824a2f049d33b2a1b4406bfc86b\",\"name\":\"Marc\",\"image\":{\"@type\":\"ImageObject\",\"inLanguage\":\"de\",\"@id\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/85b6c585f298a873f9f4be166b9fbba00a9ad2482b92863d227e5d227136d135?s=96&d=mm&r=g\",\"url\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/85b6c585f298a873f9f4be166b9fbba00a9ad2482b92863d227e5d227136d135?s=96&d=mm&r=g\",\"contentUrl\":\"https:\\\/\\\/secure.gravatar.com\\\/avatar\\\/85b6c585f298a873f9f4be166b9fbba00a9ad2482b92863d227e5d227136d135?s=96&d=mm&r=g\",\"caption\":\"Marc\"},\"url\":\"https:\\\/\\\/www.clickstorm.de\\\/blog\\\/author\\\/marc\\\/\"}]}<\/script>\n<!-- \/ Yoast SEO plugin. -->","yoast_head_json":{"title":"Doctrine DBAL ab TYPO3 Version 8 nutzen - clickstorm Blog","description":"Mit der TYPO3 Version 8 wurde mit Doctrine eine Datenbankabstraktionsschicht integriert. Anhand von Codesnippets veranschaulichen wir Ihnen die Neuerungen.","robots":{"index":"index","follow":"follow","max-snippet":"max-snippet:-1","max-image-preview":"max-image-preview:large","max-video-preview":"max-video-preview:-1"},"canonical":"https:\/\/www.clickstorm.de\/blog\/doctrine-dbal-typo3-version-8\/","og_locale":"de_DE","og_type":"article","og_title":"Doctrine DBAL ab TYPO3 Version 8 nutzen - clickstorm Blog","og_description":"Mit der TYPO3 Version 8 wurde mit Doctrine eine Datenbankabstraktionsschicht integriert. Anhand von Codesnippets veranschaulichen wir Ihnen die Neuerungen.","og_url":"https:\/\/www.clickstorm.de\/blog\/doctrine-dbal-typo3-version-8\/","og_site_name":"clickstorm Blog","article_publisher":"https:\/\/de-de.facebook.com\/clickstorm\/","article_published_time":"2017-11-28T10:09:29+00:00","article_modified_time":"2019-09-26T14:47:21+00:00","og_image":[{"width":1170,"height":780,"url":"https:\/\/www.clickstorm.de\/blog\/wp-content\/uploads\/2017\/10\/fotolia_68079312.jpg","type":"image\/jpeg"}],"author":"Marc","twitter_card":"summary_large_image","twitter_creator":"@clickstorm_gmbh","twitter_site":"@clickstorm_gmbh","twitter_misc":{"Verfasst von":"Marc","Gesch\u00e4tzte Lesezeit":"6\u00a0Minuten"},"schema":{"@context":"https:\/\/schema.org","@graph":[{"@type":"Article","@id":"https:\/\/www.clickstorm.de\/blog\/doctrine-dbal-typo3-version-8\/#article","isPartOf":{"@id":"https:\/\/www.clickstorm.de\/blog\/doctrine-dbal-typo3-version-8\/"},"author":{"name":"Marc","@id":"https:\/\/www.clickstorm.de\/blog\/#\/schema\/person\/594fb824a2f049d33b2a1b4406bfc86b"},"headline":"Doctrine DBAL ab TYPO3 Version 8 nutzen","datePublished":"2017-11-28T10:09:29+00:00","dateModified":"2019-09-26T14:47:21+00:00","mainEntityOfPage":{"@id":"https:\/\/www.clickstorm.de\/blog\/doctrine-dbal-typo3-version-8\/"},"wordCount":789,"commentCount":10,"publisher":{"@id":"https:\/\/www.clickstorm.de\/blog\/#organization"},"image":{"@id":"https:\/\/www.clickstorm.de\/blog\/doctrine-dbal-typo3-version-8\/#primaryimage"},"thumbnailUrl":"https:\/\/www.clickstorm.de\/blog\/wp-content\/uploads\/2017\/10\/fotolia_68079312.jpg","keywords":["CMS","Datenbank","Entwicklung","PHP","TYPO3"],"articleSection":["CMS"],"inLanguage":"de","potentialAction":[{"@type":"CommentAction","name":"Comment","target":["https:\/\/www.clickstorm.de\/blog\/doctrine-dbal-typo3-version-8\/#respond"]}]},{"@type":"WebPage","@id":"https:\/\/www.clickstorm.de\/blog\/doctrine-dbal-typo3-version-8\/","url":"https:\/\/www.clickstorm.de\/blog\/doctrine-dbal-typo3-version-8\/","name":"Doctrine DBAL ab TYPO3 Version 8 nutzen - clickstorm Blog","isPartOf":{"@id":"https:\/\/www.clickstorm.de\/blog\/#website"},"primaryImageOfPage":{"@id":"https:\/\/www.clickstorm.de\/blog\/doctrine-dbal-typo3-version-8\/#primaryimage"},"image":{"@id":"https:\/\/www.clickstorm.de\/blog\/doctrine-dbal-typo3-version-8\/#primaryimage"},"thumbnailUrl":"https:\/\/www.clickstorm.de\/blog\/wp-content\/uploads\/2017\/10\/fotolia_68079312.jpg","datePublished":"2017-11-28T10:09:29+00:00","dateModified":"2019-09-26T14:47:21+00:00","description":"Mit der TYPO3 Version 8 wurde mit Doctrine eine Datenbankabstraktionsschicht integriert. Anhand von Codesnippets veranschaulichen wir Ihnen die Neuerungen.","breadcrumb":{"@id":"https:\/\/www.clickstorm.de\/blog\/doctrine-dbal-typo3-version-8\/#breadcrumb"},"inLanguage":"de","potentialAction":[{"@type":"ReadAction","target":["https:\/\/www.clickstorm.de\/blog\/doctrine-dbal-typo3-version-8\/"]}]},{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/www.clickstorm.de\/blog\/doctrine-dbal-typo3-version-8\/#primaryimage","url":"https:\/\/www.clickstorm.de\/blog\/wp-content\/uploads\/2017\/10\/fotolia_68079312.jpg","contentUrl":"https:\/\/www.clickstorm.de\/blog\/wp-content\/uploads\/2017\/10\/fotolia_68079312.jpg","width":1170,"height":780,"caption":"Frau mit Fernglas und Weihnachtsm\u00fctze"},{"@type":"BreadcrumbList","@id":"https:\/\/www.clickstorm.de\/blog\/doctrine-dbal-typo3-version-8\/#breadcrumb","itemListElement":[{"@type":"ListItem","position":1,"name":"Home","item":"https:\/\/www.clickstorm.de\/blog\/"},{"@type":"ListItem","position":2,"name":"Doctrine DBAL ab TYPO3 Version 8 nutzen"}]},{"@type":"WebSite","@id":"https:\/\/www.clickstorm.de\/blog\/#website","url":"https:\/\/www.clickstorm.de\/blog\/","name":"clickstorm Blog","description":"Neuigkeiten rund um Webentwicklung","publisher":{"@id":"https:\/\/www.clickstorm.de\/blog\/#organization"},"potentialAction":[{"@type":"SearchAction","target":{"@type":"EntryPoint","urlTemplate":"https:\/\/www.clickstorm.de\/blog\/?s={search_term_string}"},"query-input":{"@type":"PropertyValueSpecification","valueRequired":true,"valueName":"search_term_string"}}],"inLanguage":"de"},{"@type":"Organization","@id":"https:\/\/www.clickstorm.de\/blog\/#organization","name":"clickstorm GmbH","url":"https:\/\/www.clickstorm.de\/blog\/","logo":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/www.clickstorm.de\/blog\/#\/schema\/logo\/image\/","url":"https:\/\/www.clickstorm.de\/blog\/wp-content\/uploads\/2017\/11\/logo.svg","contentUrl":"https:\/\/www.clickstorm.de\/blog\/wp-content\/uploads\/2017\/11\/logo.svg","caption":"clickstorm GmbH"},"image":{"@id":"https:\/\/www.clickstorm.de\/blog\/#\/schema\/logo\/image\/"},"sameAs":["https:\/\/de-de.facebook.com\/clickstorm\/","https:\/\/x.com\/clickstorm_gmbh","https:\/\/www.youtube.com\/channel\/UCEaU1eUbug6OiI4uU6vA-cA"]},{"@type":"Person","@id":"https:\/\/www.clickstorm.de\/blog\/#\/schema\/person\/594fb824a2f049d33b2a1b4406bfc86b","name":"Marc","image":{"@type":"ImageObject","inLanguage":"de","@id":"https:\/\/secure.gravatar.com\/avatar\/85b6c585f298a873f9f4be166b9fbba00a9ad2482b92863d227e5d227136d135?s=96&d=mm&r=g","url":"https:\/\/secure.gravatar.com\/avatar\/85b6c585f298a873f9f4be166b9fbba00a9ad2482b92863d227e5d227136d135?s=96&d=mm&r=g","contentUrl":"https:\/\/secure.gravatar.com\/avatar\/85b6c585f298a873f9f4be166b9fbba00a9ad2482b92863d227e5d227136d135?s=96&d=mm&r=g","caption":"Marc"},"url":"https:\/\/www.clickstorm.de\/blog\/author\/marc\/"}]}},"_links":{"self":[{"href":"https:\/\/www.clickstorm.de\/blog\/wp-json\/wp\/v2\/posts\/2489","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/www.clickstorm.de\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/www.clickstorm.de\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/www.clickstorm.de\/blog\/wp-json\/wp\/v2\/users\/7"}],"replies":[{"embeddable":true,"href":"https:\/\/www.clickstorm.de\/blog\/wp-json\/wp\/v2\/comments?post=2489"}],"version-history":[{"count":11,"href":"https:\/\/www.clickstorm.de\/blog\/wp-json\/wp\/v2\/posts\/2489\/revisions"}],"predecessor-version":[{"id":4179,"href":"https:\/\/www.clickstorm.de\/blog\/wp-json\/wp\/v2\/posts\/2489\/revisions\/4179"}],"wp:featuredmedia":[{"embeddable":true,"href":"https:\/\/www.clickstorm.de\/blog\/wp-json\/wp\/v2\/media\/2652"}],"wp:attachment":[{"href":"https:\/\/www.clickstorm.de\/blog\/wp-json\/wp\/v2\/media?parent=2489"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/www.clickstorm.de\/blog\/wp-json\/wp\/v2\/categories?post=2489"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/www.clickstorm.de\/blog\/wp-json\/wp\/v2\/tags?post=2489"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}