I have issue with PHP Leaf framework database operation which returns “0” instead of last inserted record id.
My PHP version is 8.2.12.
There is a code.
app/routes/__app.php
app()->get('/apiv1/test', function () {
$res = db()
->insert('item_schemas')
->params([
'table_name' => 'hat',
'created_at' => Carbon::now(),
'updated_at' => null
])->execute();
$itemSchemaId = db()->lastInsertID();
response()->json([
'itemSchemaId' => $itemSchemaId,
'errors' => $res ? 'No errors' : db()->errors(),
'res' => $res
]);
});
public/index.php
<?php
/*
|--------------------------------------------------------------------------
| Switch to root path
|--------------------------------------------------------------------------
|
| Point to the application root directory so leaf can accurately
| resolve app paths.
|
*/
chdir(dirname(__DIR__));
/*
|--------------------------------------------------------------------------
| Register The Auto Loader
|--------------------------------------------------------------------------
|
| Composer provides a convenient, automatically generated class loader
| for our application. We just need to utilize it! We'll require it
| into the script here so that we do not have to worry about the
| loading of any our classes "manually". Feels great to relax.
|
*/
require dirname(__DIR__) . '/vendor/autoload.php';
/*
|--------------------------------------------------------------------------
| Bring in (env)
|--------------------------------------------------------------------------
|
| Quickly use our environment variables
|
*/
try {
DotenvDotenv::createUnsafeImmutable(dirname(__DIR__))->load();
} catch (Throwable $th) {
trigger_error($th);
}
/*
|--------------------------------------------------------------------------
| Load application paths
|--------------------------------------------------------------------------
|
| Decline static file requests back to the PHP built-in webserver
|
*/
if (php_sapi_name() === 'cli-server') {
$path = realpath(__DIR__ . parse_url($_SERVER['REQUEST_URI'], PHP_URL_PATH));
if (is_string($path) && __FILE__ !== $path && is_file($path)) {
return false;
}
unset($path);
}
/*
|--------------------------------------------------------------------------
| Attach blade view
|--------------------------------------------------------------------------
|
| Templating has been disabled because you chose the MVC for APIs starter.
| If you want to use blade in your application,
| you can uncomment the line below.
|
*/
// LeafConfig::attachView(LeafBlade::class);
/*
|--------------------------------------------------------------------------
| Load Leaf configuration
|--------------------------------------------------------------------------
|
| Leaf MVC allows you to customize Leaf and it's modules using
| configuration files defined in the config folder. This line
| loads the configuration files and makes them available to
| your application.
|
*/
LeafCore::loadApplicationConfig();
/*
|--------------------------------------------------------------------------
| Sync Leaf Db with ORM and connect
|--------------------------------------------------------------------------
|
| Sync Leaf Db with ORM and connect to the database
| This allows you to use Leaf Db without having
| to initialize it in your controllers.
|
| If you want to use a different connection from those
| used in your models, you can remove the line below and
| add your own connection with:
| db()->connect(...)
|
| **Uncomment the line below to use Leaf Db**
| **You don't need this line to use Leaf Auth**
*/
db()->autoConnect();
/*
|--------------------------------------------------------------------------
| Load custom libraries
|--------------------------------------------------------------------------
|
| You can load your custom libraries here. If you have
| anything defined in your lib folder, you can load
| them here. Simply uncomment the line below.
|
*/
// LeafCore::loadLibs();
/*
|--------------------------------------------------------------------------
| Run your Leaf MVC application
|--------------------------------------------------------------------------
|
| This line brings in all your routes and starts your application
|
*/
LeafCore::runApplication();
composer.json
{
"name": "leafs/mvc",
"version": "3.9.1",
"description": "A lightweight PHP MVC framework powered by Leaf",
"type": "library",
"keywords": [
"framework",
"leaf",
"leafPHP",
"mvc",
"leaf mvc"
],
"license": "MIT",
"authors": [
{
"name": "Michael Darko",
"email": "[email protected]",
"homepage": "https://mychi.netlify.app",
"role": "Maintainer"
},
{
"name": "Abdulbasit Rubeya",
"email": "[email protected]",
"homepage": "https://github.com/ibnsultan",
"role": "Maintainer"
}
],
"require": {
"leafs/blade": "*",
"leafs/mvc-core": "^1.11",
"leafs/leaf": "^3.7",
"leafs/csrf": "*",
"leafs/logger": "v2.0",
"leafs/cors": "*",
"leafs/auth": "^3.0",
"leafs/db": "*",
"leafs/vite": "^0.3.0",
"leafs/form": "^3.0",
"leafs/http": "^3.0",
"leafs/aloe": "^2.3",
"leafs/fs": "v2.0"
},
"require-dev": {
"fakerphp/faker": "^1.16",
"leafs/alchemy": "^2.0"
},
"autoload": {
"psr-4": {
"App\": "app/",
"Tests\": "tests/",
"Config\": "config/",
"App\Http\": "app/http/",
"App\Jobs\": "app/jobs/",
"App\Lang\": "app/lang/",
"App\Mail\": "app/mail/",
"App\Views\": "app/views/",
"App\Utils\": "app/utils/",
"App\Events\": "app/events/",
"App\Models\": "app/models/",
"App\Mailers\": "app/mailers/",
"App\Workers\": "app/workers/",
"App\Console\": "app/console/",
"App\Scripts\": "app/scripts/",
"App\Helpers\": "app/helpers/",
"App\Channels\": "app/channels/",
"App\Services\": "app/services/",
"App\Middleware\": "app/middleware/",
"App\Components\": "app/components/",
"App\Controllers\": "app/controllers/",
"App\Notifications\": "app/notifications/",
"App\Database\Seeds\": "app/database/seeds/",
"App\Database\Schema\": "app/database/schema/",
"App\Database\Factories\": "app/database/factories/"
},
"exclude-from-classmap": [
"app/database/migrations"
]
},
"config": {
"optimize-autoloader": true,
"sort-packages": false,
"allow-plugins": {
"pestphp/pest-plugin": true
}
},
"scripts": {
"post-root-package-install": [
"@php -r "file_exists('.env') || copy('.env.example', '.env');"",
"@php -r "if (file_exists('README2.MD')) {unlink('README.MD'); rename('README2.MD', 'README.MD');}""
],
"post-create-project-cmd": [
"@php leaf key:generate"
]
},
"minimum-stability": "dev",
"prefer-stable": true
}
app/database/migrations/2025_03_18_075024_create_item_schema.php
<?php
use LeafDatabase;
use IlluminateDatabaseSchemaBlueprint;
class CreateItemSchema extends Database
{
/**
* Run the migrations.
* @return void
*/
public function up()
{
if (!static::$capsule::schema()->hasTable('item_schemas')) :
static::$capsule::schema()->create('item_schemas', function (Blueprint $table) {
$table->id();
$table->string('table_name')->unique();
$table->timestamp('created_at')->nullable();
$table->timestamp('updated_at')->nullable();
});
endif;
}
/**
* Reverse the migrations.
* @return void
*/
public function down()
{
static::$capsule::schema()->dropIfExists('item_schemas');
}
}
all composer packages after command
composer show -i
carbonphp/carbon-doctrine-types 2.1.0 Types to use Carbon in Doctrine
doctrine/cache 2.2.0 PHP Doctrine Cache library is a popular cache implementation that suppor...
doctrine/dbal 3.9.4 Powerful PHP database abstraction layer (DBAL) with many features for da...
doctrine/deprecations 1.1.4 A small layer on top of trigger_error(E_USER_DEPRECATED) or PSR-3 loggin...
doctrine/event-manager 2.0.1 The Doctrine Event Manager is a simple PHP event system that was built t...
doctrine/inflector 2.0.10 PHP Doctrine Inflector is a small library that can perform string manipu...
fakerphp/faker v1.24.1 Faker is a PHP library that generates fake data for you.
firebase/php-jwt v6.11.0 A simple library to encode and decode JSON Web Tokens (JWT) in PHP. Shou...
graham-campbell/result-type v1.1.3 An Implementation Of The Result Type
illuminate/bus v8.83.27 The Illuminate Bus package.
illuminate/collections v8.83.27 The Illuminate Collections package.
illuminate/container v8.83.27 The Illuminate Container package.
illuminate/contracts v8.83.27 The Illuminate Contracts package.
illuminate/database v8.83.27 The Illuminate Database package.
illuminate/events v8.83.27 The Illuminate Events package.
illuminate/filesystem v8.83.27 The Illuminate Filesystem package.
illuminate/macroable v8.83.27 The Illuminate Macroable package.
illuminate/pipeline v8.83.27 The Illuminate Pipeline package.
illuminate/support v8.83.27 The Illuminate Support package.
illuminate/view v8.83.27 The Illuminate View package.
jenssegers/blade v1.4.0 The standalone version of Laravel's Blade templating engine for use outs...
leafs/alchemy 2.2 Integrated testing/style fixing tool for your PHP apps
leafs/aloe 2.5.1 Overpowered command line tool for your leaf apps.
leafs/anchor v1.6.2 Leaf PHP util module
leafs/auth v3.4.1 Leaf PHP auth helper
leafs/blade v4.0 Leaf PHP Framework adaptation of jenssegers/blade package
leafs/cors v1.2 Leaf PHP cors config
leafs/csrf v0.5.4 Leaf CSRF security patch for leaf anchor
leafs/date v2.2 Leaf PHP date module
leafs/db v4.0.1 Leaf PHP db module.
leafs/exception v3.6.3 Error handler for leaf (fork of whoops)
leafs/form v3.2 Simple straightup data validation
leafs/fs v2.0 Leaf PHP session + flash modules
leafs/http v3.5 Http abstraction for Leaf PHP
leafs/leaf v3.12 Elegant PHP for modern developers
leafs/logger v2.0 Leaf PHP logger utility
leafs/mvc-core v1.11.1 Core files specific to MVC based leaf frameworks like Leaf MVC and Leaf ...
leafs/password v1.0 Leaf PHP password helper
leafs/session v4.0.1 Leaf PHP session + flash modules
leafs/vite v0.3.0 Server component for Vite
nesbot/carbon 2.73.0 An API extension for DateTime that supports 281 different languages.
nikic/php-parser v4.19.4 A PHP parser written in PHP
phpoption/phpoption 1.9.3 Option Type for PHP
psr/cache 3.0.0 Common interface for caching libraries
psr/clock 1.0.0 Common interface for reading the clock.
psr/container 1.1.2 Common Container Interface (PHP FIG PSR-11)
psr/log 2.0.0 Common interface for logging libraries
psr/simple-cache 1.0.1 Common interfaces for simple caching
psy/psysh v0.11.22 An interactive shell for modern PHP.
symfony/console v5.4.47 Eases the creation of beautiful and testable command line interfaces
symfony/deprecation-contracts v3.5.1 A generic function and convention to trigger deprecation notices
symfony/finder v5.4.45 Finds files and directories via an intuitive fluent interface
symfony/polyfill-ctype v1.31.0 Symfony polyfill for ctype functions
symfony/polyfill-intl-grapheme v1.31.0 Symfony polyfill for intl's grapheme_* functions
symfony/polyfill-intl-normalizer v1.31.0 Symfony polyfill for intl's Normalizer class and related functions
symfony/polyfill-mbstring v1.31.0 Symfony polyfill for the Mbstring extension
symfony/polyfill-php73 v1.31.0 Symfony polyfill backporting some PHP 7.3+ features to lower PHP versions
symfony/polyfill-php80 v1.31.0 Symfony polyfill backporting some PHP 8.0+ features to lower PHP versions
symfony/process v6.4.19 Executes commands in sub-processes
symfony/service-contracts v3.5.1 Generic abstractions related to writing services
symfony/string v6.4.15 Provides an object-oriented API to strings and deals with bytes, UTF-8 c...
symfony/translation v6.4.19 Provides tools to internationalize your application
symfony/translation-contracts v3.5.1 Generic abstractions related to translation
symfony/var-dumper v6.4.18 Provides mechanisms for walking through any arbitrary PHP variable
symfony/yaml v6.4.18 Loads and dumps YAML files
vlucas/phpdotenv v5.6.1 Loads environment variables from `.env` to `getenv()`, `$_ENV` and `$_SE...
voku/portable-ascii 1.6.1 Portable ASCII library - performance optimized (ascii) string functions ...
And result is:
{
"itemId": "0"
}
MySQL connection is established correct and record is inserted to the database, db()->lastInsertId() should returns valid record Id. Thanks very much for help.
EDIT:
Result after var_dump:
object(PDOStatement)#36 (1) {
["queryString"]=>
string(78) "INSERT INTO item_schemas (table_name,created_at,updated_at) VALUES (?,?,?)"
}
API result:
{
"itemSchemaId": "0",
"errors": "No errors",
"res": {
"queryString": "INSERT INTO item_schemas
(table_name,created_at,updated_at) VALUES (?,?,?)"
}
}
After Explain query:
"query": [
{
"id": 1,
"select_type": "INSERT",
"table": "item_schemas",
"partitions": null,
"type": "ALL",
"possible_keys": null,
"key": null,
"key_len": null,
"ref": null,
"rows": null,
"filtered": null,
"Extra": null
}
],
Explain query:
$query = db()->query("EXPLAIN " . "INSERT INTO item_schemas (table_name,created_at,updated_at) VALUES ('glovesssssssssssssssdsssss','2025-03-23 10:29:29',NULL)")->all();
Table structure with EXPLAIN:
{
"query": [
{
"Field": "id",
"Type": "bigint(20) unsigned",
"Null": "NO",
"Key": "PRI",
"Default": null,
"Extra": "auto_increment"
},
{
"Field": "table_name",
"Type": "varchar(255)",
"Null": "NO",
"Key": "UNI",
"Default": null,
"Extra": ""
},
{
"Field": "created_at",
"Type": "timestamp",
"Null": "YES",
"Key": "",
"Default": null,
"Extra": ""
},
{
"Field": "updated_at",
"Type": "timestamp",
"Null": "YES",
"Key": "",
"Default": null,
"Extra": ""
}
}