2

Can one instantiate a jdatabase object without the Joomla application? The obvious use case is when you want to open a direct endpoint into some standalone code in your site for an api or cron etc. and wish to avoid a) the performance hit of bootstrapping the whole Joomla application when you only need 1 class, and b) rewriting the queries that your Joomla application and api endpoint share.

I see there is this approach of just extracting and jiggling the code:

http://www.solutionsamir.com/20110720155/Programming/PHP/Stand-Alone-Joomla-Database-Abstraction-Class.html

but I'm hoping that someone has attempted what I'm attempting before I start digging into the library.

2 Answers 2

2

Without the bootstrap file being available I loaded the framework without the application to check the performance like this in a folder called app.

$time_start = microtime(1);

define('_JEXEC', 1);

$base = str_replace("/app", "", __DIR__);

define('JPATH_BASE', $base);

require_once JPATH_BASE . '/includes/defines.php';
require_once JPATH_BASE . '/includes/framework.php';

$db = JFactory::getDBO();
$query = $db->getQuery(true)
    ->select('*')
    ->from($db->qn('#__users'));
$db->setQuery($query);

$users = $db->loadObjectList();

echo "<pre>" . print_r($users,1) . "</pre>";
echo microtime(1) - $time_start;
die();

And then put

$time_start = microtime(1);

into the top of Joomla's index.php file and then ran the following script in the entry file of a dummy component with a menu item routing to a view of the component:

defined('_JEXEC') or die;

global $time_start;

$db = JFactory::getDBO();
$query = $db->getQuery(true)
    ->select('*')
    ->from($db->qn('#__users'));
$db->setQuery($query);

$users = $db->loadObjectList();

echo "<pre>" . print_r($users,1) . "</pre>";
echo microtime(1) - $time_start;
die();

Performance Results

without Joomla application

  • 0.034259080886841
  • 0.03374195098877
  • 0.034512996673584
  • 0.034684181213379

with Joomla application > router > menu + component

  • 0.24458599090576
  • 0.29617881774902
  • 0.29315781593323
  • 0.3031439781189

I think that is probably enough of a performance gain for me to stop looking for a faster approach and having the whole of the platform will probably be useful anyhow. But if anyone has any alternative slimmed down ways to serve up custom api endpoints using bits of the cms I would be interested to hear.

1

Yes, this is possible. You'll need to include the bootstrap.php which will execute the autoloader, allowing you to call the namespaced Database framework package.

Here is an example:

define('_JEXEC', 1);
define('JPATH_BASE', __DIR__);

require JPATH_BASE . '/includes/defines.php';
require JPATH_BASE . '/libraries/bootstrap.php';

// Make the database driver
$dbFactory = new Joomla\Database\DatabaseFactory;

$db = $dbFactory->getDriver(
    'mysqli', [
        'host'     => 'localhost',
        'user'     => 'MY DATABASE USERNAME',
        'password' => 'MY DATABASE PASSWORD',
        'database' => 'MY DATABASE NAME',
        'prefix'   => 'xxx_'
    ]
);

$query = $db->getQuery(true)
    ->select('*')
    ->from($db->qn('#__users'));
$db->setQuery($query);

$users = $db->loadObjectList();

This example assumes the standalone PHP file is in the root of your Joomla site, so you may need to change line 2, depending on where you're file resides.

Hope this helps

6
  • Much thanks for the suggestion. The bootstrap.php doesn't seem to exist anymore. See my answer for other details. Dec 20, 2017 at 3:42
  • The bootstrap.php is located in the libraries directory. What version of Joomla are you using?
    – Lodder
    Dec 20, 2017 at 9:33
  • I’m using 3.8.3. The bootstrap.php is new in Joomla 4. It does look like it will do the job, just in the future tho. Dec 20, 2017 at 20:21
  • in which case you should be able to import cms.php instead
    – Lodder
    Dec 20, 2017 at 21:25
  • Switching bootstrap.php for cms.php leads to: Fatal error: Class 'JClassLoader' not found in /home/xxxx/public_html/libraries/cms.php on line 40 Dec 23, 2017 at 1:55

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.