Real Values.
Bye bye $GLOBALS['TYPO3_DB']
Start using Doctrine DBAL in your Extension
Real Values.
About
▪ Senior TYPO3 Developer @ sitegeist
▪ Working with TYPO3 since version 3.8
▪ TYPO3 developer since 2004
▪ TYPO3 core developer since 2015
▪ Cartographer, Food Blogger and
Square Dancer
▪ Twitter: @buccaneer23
Jan Helke
Real Values.
What's Doctrine
•Framework for PHP
•Object-relational mapper (ORM)
•Provides database abstraction layer (DBAL)
Management Summary
Real Values.
• Replacement of $GLOBALS['TYPO3_DB']->exec_SELECTgetRows
• Because MySQL only (or slow due to DBAL Extension)
• Doctrine supports multiple database vendors
• MySQL SAP Sybase SQL Anywhere
• Oracle SQLite
• Microsoft SQL Server Drizzle
• PostgreSQL
Management Summary
Why switch to Doctrine DBAL?
Real Values.
Your benefits
• Agencies
• Potential TYPO3 customer base to all non-MySQL users.
• Customers
• A reliable industry standard
• Developers
• More fun because of easy API and create beautiful code.
Management Summary
Real Values.
What about Extbase extensions?
•If you use just native Extbase function
•We got you covered. Extbase QueryBuilder is already
converted
•If you create custom / overwrite native functions using
$GLOBALS['TYPO3_DB'] (e.g. in your repositories)
•Stay awake and pay attention
Management Summary
Real Values.
But what about performance?
Tests showed:
•On a nearly perfect configured system:
- 0.5 percent
•On a random casual configured system:
+ 3.0 percent
Management Summary
Real Values.
It's dead Jim (was "Deadline")
• $GLOBALS['TYPO3_DB'] will only work until TYPO3 8 LTS
•Is already removed from master since April 2017
•Can only be reinstalled with
composer require friendsoftypo3/typo3db-legacy
•No back-port to TYPO3 7 LTS
Management Summary
Real Values.
End of management overview
• If you just wanted to know what the state of play is and how to scare your
boss, these were the facts.
Go and spread fear!
• If you want to migrate right now with your project
Stay!
Warning: Next slides might contain some chunks of code.
Management Summary
Real Values.
Query Builder
•Swiss army knife for database handling
•Knows the database vendor for every table
•Tables can be stored on different vendors databases
•Needs to be initialized for every table
$queryBuilder =
GeneralUtility::makeInstance(ConnectionPool::class)
->getQueryBuilderForTable('sys_log');
Developer introduction
Real Values.
Simple select [past]
Short example for warming up.
$rows = $this->getDatabaseConnection()
->exec_SELECTgetRows(
'uid',
'pages,
'pid=' . $pid
);
Developer introduction
Real Values.
Simple select [future][now]
$rows = $queryBuilder
->select('uid')
->from('pages')
->where(
$queryBuilder->expr()->eq( <---|
'pid', |
$queryBuilder |
->createNamedParameter( |-- read: "where 'pid' = $pid"
$pid, | we will come to that later
PDO::PARAM_INT |
) <---|
)
)
->execute()
->fetchAll();
If you want only a single row, just ->fetch() it.
Developer introduction
Real Values.
Nesting conditions [past]
$rows = $this->getDatabaseConnection()
->exec_SELECTgetRows(
'uid, userid, action, tstamp, log_data',
'sys_log',
'type = 1 ' .
' AND (action=1 OR action=3)'
);
Developer introduction
Real Values.
Nesting conditions [future][now]
$rows = $queryBuilder
->select('uid', 'userid', 'action', 'tstamp', 'log_data')
->from('sys_log')
->where(
$queryBuilder->expr()->eq( <---|
'type', |
$queryBuilder->createNamedParameter(. |-- read: "where 'type' = 1"
1, |
PDO::PARAM_INT |
) <---|
)
)
->andWhere(
$queryBuilder->expr()->orX(
$queryBuilder->expr()->eq('action', 1), <-- createNamedParameter skipped
$queryBuilder->expr()->eq('action', 3) <-- here because lack of space
)
)->execute()->fetchAll();
Developer introduction
Real Values.
Insert
$queryBuilder
->insert('sys_history')
->values(
[
'snapshot','some_snapshot'
]
)
->execute();
Developer introduction
Real Values.
Update
$queryBuilder
->update('sys_history')
->where(
$queryBuilder->expr()->eq(
'uid',
$queryBuilder->createNamedParameter(
$uid,
PDO::PARAM_INT
)
)
)
->set('snapshot', 'some_snapshot')
->set('random_column', 'random_value')
->execute();
Developer introduction
Real Values.
Security announcement
->where(
$queryBuilder
->expr()
->eq('uid',$uid)
)
• Always use ->createNamedParameter() around any input,
no matter where it comes from.
• The second argument of ->expr() shall always either a
call to ->createNamedParameter() or ->quoteIdentifier().
Developer introduction
Real Values.
Security announcement
->where(
$queryBuilder
->expr()
->eq(
'uid',
$queryBuilder
->createNamedParameter(
$uid
PDO::PARAM_INT
)
)
)
Developer introduction
Real Values.
Final highlight
All of you Extbase Query Builder dev know the ultimate pain.
Doctrine DBAL has the answer.
echo $queryBuilder
->select('*')
->from('sys_history')
->getSQL();
If you get something like "dcValue1" in some clause, have a look at
$queryBuilder->getParameters.
Developer introduction
Real Values.
Restriction builder
•The new "enableFields" magic
•Handled by the query builder
•Context related restriction container
•Show everything regardless of hidden, deleted ...
$queryBuilder
->getRestrictions()
->removeAll();
Developer introduction
Real Values.
Boundless restrictions
•Create your own restriction set
•Have a look at
TYPO3CMSCoreDatabaseQueryRestrictionDefaultRestrictionContainer
$queryBuilder
->setRestrictions(OwnNamespaceCustomRestrictionContainer);
Developer introduction
Real Values.
Best practices
$queryBuilder
->getRestrictions()
->removeByType(HiddenRestriction::class)
->removeByType(StartTimeRestriction::class)
->removeByType(EndTimeRestriction::class);
vs.
$queryBuilder
->getRestrictions()
->removeAll()
->add(GeneralUtility::makeInstance(DeletedRestriction::class));
Developer introduction
Real Values.
Thank you. Questions?
Real Values.
Sources
Docs » TYPO3 API » Database Access
http://bit.ly/2wWhBxp
(Thanks to Christian Kuhn for this awesome documentation)
My Blog
http://bit.ly/2ytwSXt
Sources

Bye bye $GLOBALS['TYPO3_DB']