// sync userlevel
$app->get('/ulvsync/{name}', function ($request, $response, $args) {
$name = $args\["name"\] ?? null; // Get the input value
if ($name !== null) {
$response = $response->withJson(ExecuteStatement(" UPDATE updateuserlevel SET userlevel=role WHERE id='" . AdjustSql($name) . "'")); // Select the record by name and return as JSON
}
return $response;
});
this was my code in 2024 PHM . I am totaly lost on how to implemet in 2026
I did, I just don't know where to put the custom API code in PHPmaker to avoid it getting over written . i saw related code in controllers\ApiController .
When you open old projects in v2026, PHPMaker will try to convert your Route_Action and Api_Action server events (which used closures) to two controllers, RouteActionController and ApiActionController as Custom Files (for Symfony).
After conversion, you can maintain your code in the Code -> Custom Templates -> Table-Specific -> Custom File -> Content section of the custom files.
Note: Custom Files will not be get overwritten (don't customize the generated file). To make your code performs better for the long run, you should update your controller action's arguments and the response object as explained in the migration guide. (i.e. Update your code for Symfony framework.)
Thank you .This works for old project but a new project in phpmaker 2026 , i followed the documentation, Example 4 - Add Controller
Add your own controller and action(s) to the project:
File Name - Use a unique file name with file extension .php and the file name MUST be same as the class name. Use PascalCase with a Controller suffix, e.g. MyCustomController, to clearly indicate it's a controller.
Include Common Files - DISABLE IT. It is NOT applicable to classes.
Caption - NOT applicable.
Path - Set the path as "controllers" (no quotes).
Content - I created a controller in a custom file ,
My code :
<?php
namespace PHPMaker2026\serverapi;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\StreamedResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpFoundation\EventStreamResponse;
use Symfony\Component\HttpFoundation\StreamedJsonResponse;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Routing\Requirement\Requirement;
use Symfony\Component\Security\Http\Attribute\IsGranted;
class MyCustomController
{
#[Route(
'/hello/{name}',
name: 'hello',
methods: ['GET', 'OPTIONS']
)]
public function hello(string $name): Response
{
return new Response("Hello, " . $name);
}
}
http://localhost/pmp2026/project/server/api/hello/John gave me error:
{
"error": "No route found for \\"GET http://localhost/pmp2026/project/server/api/hello/John"
}
#[Route(
'/getproduct/{name}',
methods: ['GET', 'OPTIONS'],
name: 'get_user_data'
)]
public function getsingleProduct(string $name): Response
{
$id = (int) AdjustSql($name);
$row = ExecuteRow(
"SELECT * FROM producttbl WHERE id = " . $id
);
return new JsonResponse($row ?? []);
}
i Know $id = (int) AdjustSql($name); add some protection from sql attack but i prefer proper prepared statment . How is this implemented ?
this worked use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\HttpFoundation\JsonResponse;
use Symfony\Component\HttpFoundation\StreamedResponse;
use Symfony\Component\HttpFoundation\RedirectResponse;
use Symfony\Component\HttpFoundation\BinaryFileResponse;
use Symfony\Component\HttpFoundation\EventStreamResponse;
use Symfony\Component\HttpFoundation\StreamedJsonResponse;
use Symfony\Component\Routing\Attribute\Route;
use Symfony\Component\Routing\Requirement\Requirement;
use Symfony\Component\Security\Http\Attribute\IsGranted;
use Doctrine\DBAL\Connection;
use Doctrine\ORM\EntityManagerInterface;
#[Route(
'/getproduct/{name}',
methods: ['GET', 'OPTIONS'],
name: 'get_user_data'
)]
public function getsingleProduct(string $name): Response
{
$id = (int) $name;
// Get the connection from EntityManager
$connection = $entityManager->getConnection();
$sql = 'SELECT * FROM producttbl WHERE id = :id';
// Execute with parameters (automatically prepared/bound)
$result = $connection->executeQuery($sql, [
'id' => $id,
]);
$row = $result->fetchAssociative();
return new JsonResponse($row ?? []);
}