Aggrid Php Example Updated [best] (2026)
Integrating AG Grid with PHP allows you to build high-performance, enterprise-grade data tables with features like server-side pagination, sorting, and filtering. This guide provides a modern example of connecting AG Grid to a PHP/MySQL backend for a full CRUD (Create, Read, Update, Delete) experience. 1. Database and Environment Setup
Before writing code, ensure you have a local server like XAMPP running with Apache and MySQL.
Database Preparation:Create a table named products to store your grid data:
CREATE DATABASE inventory_db; USE inventory_db; CREATE TABLE products ( id INT AUTO_INCREMENT PRIMARY KEY, name VARCHAR(255) NOT NULL, category VARCHAR(100), price DECIMAL(10, 2) ); Use code with caution. 2. The Frontend: AG Grid Implementation
Use the AG Grid Community edition via CDN for a quick setup. index.html:
Use code with caution. 3. The Backend: PHP & MySQL API
Your PHP scripts will handle data retrieval and updates using JSON as the bridge.
fetch.php (Read Operation):This script retrieves data from MySQL and returns it to the grid as a JSON array.
query("SELECT * FROM products"); echo json_encode($result->fetch_all(MYSQLI_ASSOC)); ?> Use code with caution.
update.php (Update Operation):When a cell is edited in the grid, this script receives the updated row data.
prepare("UPDATE products SET name=?, category=?, price=? WHERE id=?"); $stmt->bind_param("ssdi", $data['name'], $data['category'], $data['price'], $data['id']); $stmt->execute(); ?> Use code with caution. 4. Advanced: Server-Side Row Model (SSRM)
This script acts as your API. It connects to a database and returns data in JSON format, which AG Grid expects. query( "SELECT id, name, email, role FROM users" ); $data = $stmt->fetchAll(PDO::FETCH_ASSOC); json_encode($data); (PDOException $e) json_encode([ => $e->getMessage()]); ?> Use code with caution. Copied to clipboard 2. The Frontend (index.html)
You include the AG Grid library via CDN and use JavaScript to initialize the grid and fetch data from your PHP script. < >AG Grid PHP Example "https://jsdelivr.net" "ag-theme-alpine" "height: 500px; width:100%;" > const columnDefs = [ field: , sortable: true, filter: true , field:
, sortable: true, filter: true, editable: true , field: , filter: true , field:
];
const gridOptions =
columnDefs: columnDefs,
pagination: true,
// Capture updates to cells
onCellValueChanged: (params) =>
console.log( 'Data updated:'</p>
, params.data); // Here you would use fetch() to POST updates back to a PHP script ;
// Initialize the grid
const gridDiv = document.querySelector(</p>
); const gridApi = agGrid.createGrid(gridDiv, gridOptions);
// Fetch data from PHP backend
fetch( 'data.php'</p>
) .then(response => response.json()) .then(data => gridApi.setGridOption( , data));
event. You can then send the updated row data back to a PHP script using Grid Methods
: For more complex updates, such as programmatically changing a single cell, you can use grid API methods like rowNode.setDataValue(col, value) Row Selection
: If you need to perform actions on specific rows, enable selection and use gridApi.getSelectedRows() to retrieve the data for processing.
For developers who prefer a more "plug-and-play" PHP solution, alternatives like offer simplified rendering with fewer lines of code. PHP code for handling the POST request to save these grid updates to your database? How to get the data of selected rows in ag-Grid
How to get the data of selected rows in AG Grid * Enable Row Selection. Enable row selection in AG Grid using the grid options. .. AG Grid Blog JavaScript Data Grid - Updating Data - AG Grid
Building a High-Performance Data Grid: AG Grid & PHP (2026 Guide)
When your dataset grows from hundreds to hundreds of thousands of rows, client-side rendering isn't enough. You need a robust server-side strategy. Below is an updated guide and example for integrating AG Grid (v35+) 1. The Frontend: Modern AG Grid Setup For 2026, we utilize the Server-Side Row Model (SSRM)
. This allows the grid to only fetch the data it needs to display, rather than loading the entire database at once. < "https://jsdelivr.net" "height: 500px; width: 100%;" "ag-theme-alpine" > const columnDefs = [ field: 'agNumberColumnFilter' , field: 'agTextColumnFilter' , field: , field:
];
const gridOptions =
columnDefs: columnDefs,
rowModelType: 'serverSide'</p>
, // Enables SSRM pagination: true, paginationPageSize: , cacheBlockSize: ;
const gridDiv = document.querySelector(</p>
); const api = agGrid.createGrid(gridDiv, gridOptions);
// Fetch data from PHP backend
const datasource =
getRows: (params) =>
fetch( 'datasource.php' ,
method:</p>
, body: JSON.stringify(params.request), headers: 'Content-Type' 'application/json'
) .then(response => response.json()) .then(data => params.success( rowData: data.rows, rowCount: data.total ); ) .catch(error => params.fail()); ;
api.setGridOption( 'serverSideDatasource' , datasource);
</ Use code with caution. Copied to clipboard 2. The Backend: Scalable PHP Logic Your PHP script must handle the filterModel startRow/endRow parameters sent by AG Grid. Using is critical for security to prevent SQL injection. // datasource.php 'Content-Type: application/json' );
$input = json_decode(file_get_contents( 'php://input' ), true);
$startRow = $input[ 'startRow' ; $endRow = $input[ ; $limit = $endRow - $startRow; // Database Connection 'mysql:host=localhost;dbname=sports_db' // 1. Build the WHERE clause from AG Grid's filterModel " WHERE 1=1 " 'filterModel' 'filterModel' $col => $filter) // Simple example for text filter 'filterType' ) $where .= " AND $col LIKE " . $pdo->quote( . $filter[ ); } // 2. Fetch Paginated Data "SELECT * FROM athletes $where LIMIT :start, :limit" ; $stmt = $pdo->prepare($sql); $stmt->bindValue( , (int)$startRow, PDO::PARAM_INT); $stmt->bindValue(
, (int)$limit, PDO::PARAM_INT); $stmt->execute(); $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); // 3. Get Total Record Count for Pagination UI $totalSql = "SELECT COUNT(*) FROM athletes $where" ; $total = $pdo->query($totalSql)->fetchColumn(); json_encode([ => (int)$total ]); Use code with caution. Copied to clipboard Key Considerations for 2026 Version Updates : AG Grid v35 introduces improved Formula Editors BigInt support , making it ideal for financial PHP applications. : Always use prepared statements $pdo->quote() when handling filterModel keys to prevent malicious SQL injections. State Management : If you are using modern PHP frameworks like , consider leveraging its built-in paginators to simplify the server-side Excel export ChatGPT or Copilot – which is better for PHP development?
Implementing AG Grid with PHP involves a two-part architecture: a PHP backend to serve data (usually in JSON format) and a JavaScript frontend to render the grid. 1. The PHP Backend (data.php)
Your PHP script should fetch data from a database and return it as a JSON array. This is the "updated" way to handle modern grid requests.
query("SELECT id, name, model, price FROM cars"); $results = $stmt->fetchAll(PDO::FETCH_ASSOC); // Output as JSON for AG Grid echo json_encode($results); catch (PDOException $e) echo json_encode(['error' => $e->getMessage()]); ?> Use code with caution. Copied to clipboard 2. The Frontend Layout (index.html)
Use the latest AG Grid Community Edition via CDN. The script fetches data from your PHP file using fetch().
Use code with caution. Copied to clipboard Key Update Notes
Grid Initialization: In newer versions (v31+), use agGrid.createGrid() instead of the older new agGrid.Grid().
Data Updates: Use gridApi.setGridOption('rowData', data) to dynamically refresh the grid. aggrid php example updated
Server-Side Operations: For massive datasets (millions of rows), consider AG Grid Enterprise which allows PHP to handle filtering and sorting directly on the server. Angular Grid: Upgrading to AG Grid 33.0
While AG Grid is primarily a JavaScript-based library, it is commonly integrated with PHP backends to handle server-side data processing like filtering, grouping, and pagination. Updated AG Grid & PHP Integration
Modern implementations focus on using the Server-Side Row Model (SSRM) to fetch data from a PHP RESTful API.
Server-Side Logic: Your PHP script (often using frameworks like Laravel) receives a JSON request containing the grid's state (sorting, filtering, row groups) and returns a formatted JSON response containing the data and total row count.
Data Updates: You can track changes in the grid using the onCellValueChanged event to identify and send only modified rows back to your PHP backend for saving.
Performance: AG Grid uses row and column virtualization to maintain high performance even when handling millions of rows processed via your PHP server. Key Implementation Resources
Official Blog Guide: The AG Grid Blog provides a detailed walkthrough for setting up the Server-Side Row Model with Laravel and MySQL, which is the most "updated" standard for modern PHP development.
CRUD Application Patterns: For a more general approach, developers often follow a multi-part series on building CRUD applications where the "Middle Tier" is a PHP-based REST service.
Theming and UI: Recent updates (v33+) have introduced a new Theming API that makes it easier to style your grid to match your PHP application's design without deep CSS overrides. Notable "Interesting Paper" Context
While no formal academic "paper" is the primary source for this setup, the "Core Philosophy" documentation and the technical deep-dives on the AG Grid Github function as the authoritative technical references for these integrations.
Using AG Grid Server-Side row model with Angular, Laravel & MySQL
Assuming you want a concise, up-to-date PHP example showing how to load data into AG Grid (frontend) and serve it from PHP (backend) via JSON — here’s a minimal end-to-end snippet.
Frontend (index.html)
<!doctype html>
<html>
<head>
<meta charset="utf-8" />
<title>AG Grid PHP Example</title>
<script src="https://unpkg.com/ag-grid-community/dist/ag-grid-community.min.noStyle.js"></script>
<link rel="stylesheet" href="https://unpkg.com/ag-grid-community/dist/styles/ag-grid.css" />
<link rel="stylesheet" href="https://unpkg.com/ag-grid-community/dist/styles/ag-theme-alpine.css" />
<style>
html, body, #myGrid height: 100%; margin: 0; width: 100%;
</style>
</head>
<body>
<div id="myGrid" class="ag-theme-alpine"></div>
<script>
const columnDefs = [
field: "id", sortable: true, filter: true, width: 90 ,
field: "name", sortable: true, filter: true ,
field: "email", sortable: true, filter: true ,
field: "created_at", headerName: "Created", sortable: true, filter: true
];
const gridOptions =
columnDefs,
defaultColDef: resizable: true ,
pagination: true,
paginationPageSize: 20
;
const eGridDiv = document.querySelector('#myGrid');
new agGrid.Grid(eGridDiv, gridOptions);
// Fetch data from PHP endpoint
fetch('api/users.php')
.then(r =>
if (!r.ok) throw new Error('Network response was not ok');
return r.json();
)
.then(data => gridOptions.api.setRowData(data))
.catch(err => console.error('Fetch error:', err));
</script>
</body>
</html>
Backend (api/users.php)
<?php
header('Content-Type: application/json');
// Simple PDO connection — adjust DSN, user, pass for your environment
$dsn = 'mysql:host=127.0.0.1;dbname=mydb;charset=utf8mb4';
$user = 'dbuser';
$pass = 'dbpass';
try
$pdo = new PDO($dsn, $user, $pass, [
PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION,
PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC,
]);
// Basic example: return all users. For large tables, implement paging/filtering server-side.
$stmt = $pdo->query('SELECT id, name, email, created_at FROM users ORDER BY id DESC LIMIT 500');
$rows = $stmt->fetchAll();
echo json_encode($rows);
catch (PDOException $e)
http_response_code(500);
echo json_encode(['error' => 'Database error']);
Notes / suggestions (concise)
- For large datasets use server-side row model or implement paging, sorting, filtering server-side.
- Sanitize and validate parameters if you add query params (page, sort, filter).
- Serve via HTTPS in production.
- If you need AG Grid enterprise features, include the enterprise bundle and license.
Related search suggestions (useful terms)
- "ag-grid php example"
- "ag-grid server side pagination php"
- "ag-grid backend sorting filtering php"
Integrating AG Grid with PHP is a powerful way to handle large datasets with a modern, high-performance UI. Because PHP is a server-side language and AG Grid is a client-side JavaScript library, the bridge between them is typically a RESTful API that handles data fetching and updates. The Modern Architecture
In an updated stack, you move away from rendering HTML tables on the server. Instead, PHP acts as the backend engine—using a framework like Laravel or a simple Slim app—to serve JSON. AG Grid sits on the frontend, consuming that JSON. This separation allows for "Server-Side Row Model" features, where the grid only loads the data visible to the user, making it capable of handling millions of rows without crashing the browser. Data Fetching and CRUD An effective implementation involves a few key steps:
The API Endpoint: A PHP script queries your database (like MySQL) and returns the result as json_encode($data).
The Grid Configuration: On the frontend, you define columnDefs and use the fetch() API to pull from your PHP endpoint.
Updates: By using AG Grid's onCellValueChanged event, you can send an asynchronous POST or PUT request back to a PHP script to save changes to the database instantly. Security and Performance
Modern examples prioritize prepared statements (PDO) in PHP to prevent SQL injection. Additionally, with the latest AG Grid updates, you can leverage Integrated Charts and Advanced Filtering, which requires passing complex filter objects from the grid to your PHP logic to dynamically build the SQL query.
Integrating AG Grid with PHP remains a top choice for developers building data-heavy enterprise dashboards. While AG Grid is a client-side powerhouse, connecting it to a PHP backend (like Laravel or raw PHP with PDO) allows you to handle millions of rows through server-side processing.
This guide focuses on an updated implementation for 2025, utilizing modern PHP best practices and AG Grid's latest Server-Side Row Model (SSRM) features. 1. The Strategy: Server-Side Row Model (SSRM)
For large datasets, don't load everything at once. Use the SSRM to fetch data in blocks as the user scrolls.
Client-side: AG Grid sends a JSON request containing pagination, sorting, and filtering state.
Server-side (PHP): A PHP script parses this JSON, builds a dynamic SQL query, and returns only the requested "slice" of data. 2. Updated PHP Backend Implementation (Laravel Example)
Modern adapters like the AG Grid Server Side Adapter for Laravel simplify this by automatically transforming grid requests into Eloquent queries. Example Controller Snippet:
use App\Models\User; use Clickbar\AgGrid\Requests\AgGridGetRowsRequest; class UserController extends Controller public function getRows(AgGridGetRowsRequest $request) // Automatically handles filtering, sorting, and pagination return AgGridQueryBuilder::forRequest($request, User::query()) ->get(); Use code with caution. Copied to clipboard JavaScript Grid: Server-Side Row Model - AG Grid
Title: The Grid That Wouldn't Wait
Logline: A junior developer’s routine update to an AG Grid PHP example spirals into a company-wide crisis when a legacy backend refuses to play nice with modern JavaScript.
The Story
Elara, a mid-level full-stack developer at DataViz Dynamics, stared at her Jira ticket. It was the kind of task everyone dreads: "TASK #4473 – Update AG Grid PHP Example on Dev Portal."
The existing example, a dusty "AG Grid + PHP/MySQL" demo, was five years old. It used AG Grid v23.2 (two major versions behind) and raw PHP mysqli with concatenated SQL. New users trying it out kept getting errors: "undefined property: data.lastModified" and "CORS preflight fails on PUT."
Her manager, Leo, had added a note: “Make it RESTful. Add streaming. Use AG Grid v31.3. And please, make it look like we know what year it is.”
Elara smiled. She loved AG Grid – its infinite scrolling, its cell editing, its ability to handle a million rows without breaking a sweat. But marrying it with a traditional PHP backend? That was the delicate dance.
She created a new folder: ag-grid-php-example-updated/.
Step 1: The Frontend Facelift
She wrote a modern JavaScript module:
// main.js import AgGridReact from 'ag-grid-react'; import 'ag-grid-community/styles/ag-grid.css'; import 'ag-grid-community/styles/ag-theme-alpine.css';const columnDefs = [ field: 'id', filter: 'agNumberColumnFilter' , field: 'product_name', editable: true, filter: 'agTextColumnFilter' , field: 'price', editable: true, cellDataType: 'number' , field: 'last_updated', cellRenderer: (params) => new Date(params.value).toLocaleString() ];
const gridOptions = rowModelType: 'serverSide', // Server-side pagination & filtering serverSideStoreType: 'partial', cacheBlockSize: 100, columnDefs: columnDefs, onCellValueChanged: (event) => fetch('/api/rows/update', method: 'PUT', body: JSON.stringify( id: event.data.id, field: event.colDef.field, value: event.newValue ) ) ;
Beautiful. Reactive. Editable inline.
Step 2: The PHP Middleware – The Updated Example
She wrote a modern server.php using Slim Framework 4 (instead of raw mysqli), with prepared statements, PDO, and server-side row model support:
<?php // server.php - The "Updated" heart use Psr\Http\Message\ResponseInterface as Response; use Psr\Http\Message\ServerRequestInterface as Request; use Slim\Factory\AppFactory; use DI\Container;require DIR . '/vendor/autoload.php';
$container = new Container(); $container->set('db', function() $pdo = new PDO('mysql:host=localhost;dbname=grid_demo;charset=utf8mb4', 'user', 'pass'); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); return $pdo; );
AppFactory::setContainer($container); $app = AppFactory::create();
// Server-side row fetch for AG Grid $app->post('/api/grid/rows', function (Request $request, Response $response) $params = $request->getParsedBody(); $startRow = $params['startRow'] ?? 0; $endRow = $params['endRow'] ?? 100; $limit = $endRow - $startRow;
// Filter & sort parsing (simplified) $sql = "SELECT id, product_name, price, last_updated FROM products"; $countSql = "SELECT COUNT(*) as total FROM products"; $stmt = $this->get('db')->prepare("$sql LIMIT :offset, :limit"); $stmt->bindValue(':offset', $startRow, PDO::PARAM_INT); $stmt->bindValue(':limit', $limit, PDO::PARAM_INT); $stmt->execute(); $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); $totalStmt = $this->get('db')->query($countSql); $totalRows = $totalStmt->fetch()['total']; $result = [ 'rows' => $rows, 'lastRow' => $totalRows ]; return $response->withHeader('Content-Type', 'application/json')->write(json_encode($result)););
// Inline edit update $app->put('/api/rows/update', function (Request $request, Response $response) $data = json_decode($request->getBody(), true); $sql = "UPDATE products SET $data['field'] = :value WHERE id = :id"; $stmt = $this->get('db')->prepare($sql); $stmt->execute([':value' => $data['value'], ':id' => $data['id']]); return $response->withStatus(200); );
$app->run();
She added detailed README.md explaining:
- Composer install for Slim and PDO
- Nginx/Apache
.htaccessfor URL rewriting - CORS headers for local development
- How to generate 50,000 test rows using a seed script.
Step 3: The Unexpected Test
Elara pushed her branch: feature/update-ag-grid-php-example. She wrote a pull request with screenshots of the new grid – smooth infinite scroll, inline editing, server-side sorting.
But at 2:13 AM, the staging server crashed.
The logs showed a nightmare: "PHP Fatal error: Allowed memory size exhausted" when a user tried to export all 500,000 rows as CSV. The old example never had export. Her new grid had gridApi.exportDataAsCsv() – but that called the server-side post /api/grid/rows with startRow=0, endRow=null.
The PHP script tried to fetch half a million rows at once.
Step 4: The Fix and the Lesson
Elara rushed in at 7 AM. She realized: the updated example needed a streaming export endpoint, not a bulk load.
She added a new route:
$app->get('/api/export/csv', function (Request $request, Response $response)
$stmt = $this->get('db')->query("SELECT id, product_name, price, last_updated FROM products");
$response = $response->withHeader('Content-Type', 'text/csv')
->withHeader('Content-Disposition', 'attachment; filename="grid_export.csv"');
$fh = fopen('php://output', 'w');
fputcsv($fh, ['ID', 'Product Name', 'Price', 'Last Updated']);
while ($row = $stmt->fetch(PDO::FETCH_ASSOC))
fputcsv($fh, $row);
ob_flush();
flush();
fclose($fh);
return $response;
);
She updated the AG Grid example to call this export URL instead of using gridApi.exportDataAsCsv() for large datasets, adding a note: "For large data, prefer server-side streaming export."
The Resolution
By 10 AM, the pull request was merged. The updated AG Grid PHP example was live on the dev portal, with:
- Modern AG Grid v31.3 (server-side row model, inline editing, filtering)
- Slim Framework 4 + PDO (secure, fast, prepared statements)
- Streaming CSV export (no memory exhaustion)
- Detailed setup guide for Docker + PHP 8.2 + MySQL 8
That afternoon, Leo walked over. "The portal traffic doubled. Someone from a fintech startup said our example saved them three weeks of work."
Elara looked at her now-resolved Jira ticket. She added a final comment:
"Updated AG Grid PHP example to 2024 standards. Added streaming export, server-side row model, and a warning about memory limits. Note to self: never underestimate production data size."
She closed the ticket. The grid would wait for no one – but now, at least, it would handle a million rows without breaking.
End
Moral of the story: Updating an example isn’t just about new syntax – it’s about anticipating scale, securing data flow, and documenting the real-world pitfalls. And always test the export.
Integrating requires a bridge between your backend (MySQL/PostgreSQL) and the frontend grid via a JSON API. Because AG Grid is a client-side JavaScript library, the PHP portion focuses on serving data and handling server-side operations like pagination, filtering, and sorting. 1. Basic Project Structure
A modern AG Grid setup typically uses a "Fetch" pattern rather than direct PHP embedding: index.html : Loads the AG Grid library and initializes the grid. : Handles the gridOptions and fetches data from the backend. : Queries the database and returns a JSON-encoded array. 2. Frontend Setup (JavaScript)
To initialize the grid, you need to define column headers and a source. Using the latest setGridOption method is recommended for updates. javascript gridOptions = { columnDefs: [ field: , headerName: , field: , headerName: "Full Name" , { field: , headerName: , sortable: // Use pagination for large datasets pagination: , paginationPageSize: // Initialize and Fetch Data gridDiv = document.querySelector( gridApi = agGrid.createGrid(gridDiv, gridOptions);
fetch( 'data.php'
) .then(response => response.json()) .then(data => gridApi.setGridOption( Use code with caution. Copied to clipboard 3. Backend Data Source (PHP) script serves as the API. Ensure you set the correct Content-Type header so the browser interprets it as JSON. query( "SELECT id, name, email FROM users" ); $results = $stmt->fetchAll(PDO::FETCH_ASSOC); // Output JSON for AG Grid json_encode($results); (PDOException $e) json_encode([ => $e->getMessage()]); ?> Use code with caution. Copied to clipboard 4. Advanced: Server-Side Row Model For datasets with millions of rows, use the AG Grid Enterprise Server-Side Row Model
: Instead of fetching all data at once, the grid sends a request to PHP containing the start row, end row, sort parameters, and filters. PHP Handling : Use these parameters to construct a SQL query to return only the visible slice of data. 5. Key Updates for 2026 Modularization
: AG Grid v33+ uses a modular system to reduce bundle size by 20-40%. : Use the new Theming API
for deeper CSS customization without overriding complex internal rules. Browser Support
: AG Grid 27+ has officially dropped support for Internet Explorer 11. AG Grid Blog CRUD example
(Create, Read, Update, Delete) showing how to send edits back to a PHP script? solidjs-community/solid-ag-grid - GitHub
Here are some of the features that make AG Grid stand out: * Grouping / Aggregation * * Accessibility support. * Custom Filtering. What's New in AG Grid 33
This guide provides a modern implementation of AG Grid (version 35.x) using PHP 8.x as the backend. By 2026, standard practices for data grids have shifted toward using an API-first approach where PHP serves JSON to the client-side grid. 1. Front-End: Grid Setup
Modern AG Grid versions utilize createGrid rather than older constructor methods. This example uses the Client-Side Row Model for simplicity, which is ideal for datasets up to 100,000 rows.
Use code with caution. Copied to clipboard 2. Back-End: PHP API (api.php)
In 2026, PHP is primarily used as an API layer to handle database operations securely. This updated example uses PDO with prepared statements to prevent SQL injection.
PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, ]); $action = $_GET['action'] ?? ''; if ($action === 'read') // Fetch data for the grid $stmt = $pdo->query("SELECT id, name, email, role FROM users"); echo json_encode($stmt->fetchAll()); if ($action === 'update') // Basic CRUD update example $data = json_decode(file_get_contents('php://input'), true); $stmt = $pdo->prepare("UPDATE users SET name = ?, email = ? WHERE id = ?"); $stmt->execute([$data['name'], $data['email'], $data['id']]); echo json_encode(['status' => 'success']); ?> Use code with caution. Copied to clipboard 3. Key 2026 Best Practices
Virtualization: AG Grid enables row and column virtualization by default to handle large data efficiently.
Server-Side Row Model (SSRM): For millions of rows, use rowModelType: 'serverSide' to lazy-load data in chunks.
Immutable Data: Enable immutableData: true and provide a getRowId function (using your database primary key) to optimize re-renders during updates.
Security: Always use POST/PUT for updates and ensure your PHP backend validates all incoming JSON data. AG Grid What's new
A solid resource for integrating AG Grid with PHP is the Server-Side Row Model (SSRM) guide from the AG Grid blog. While many official examples use Node.js, this specific walkthrough covers the Laravel (PHP) and MySQL stack, which is highly applicable to modern PHP environments. Key Components of a PHP Implementation
To set up a production-ready AG Grid with a PHP backend, you typically need:
Grid Configuration: Set rowModelType: 'serverSide' in your JavaScript options.
Datasource: A getRows function in JS that POSTs the grid's request object to your PHP endpoint.
PHP Controller: Logic to parse the startRow, endRow, sortModel, and filterModel from the incoming JSON.
SQL Generation: Dynamically building LIMIT, OFFSET, ORDER BY, and WHERE clauses based on that grid request. Updated Resources & Libraries
AG Grid Laravel Adapter: For those using Laravel, the ag-grid-laravel package provides a pre-built adapter to handle the heavy lifting of server-side requests.
Latest Versions: As of April 2026, ensure you are referencing documentation for AG Grid v35.2.1 to utilize the latest Theming API and performance enhancements.
Full-Stack Reference: While not exclusively PHP, the AG Grid Github Examples repository contains the code for the Laravel/MySQL integration mentioned above.
💡 Pro Tip: Use a prepared statement or an ORM (like Eloquent) in your PHP backend when translating AG Grid's filterModel to SQL to prevent SQL injection vulnerabilities.
If you tell me your specific PHP framework (e.g., Laravel, Symfony, or Vanilla PHP), I can provide a more tailored code snippet for your backend controller.
Since you haven't pasted the specific code you are working on, I have drafted a generic code review based on the common architecture of an AG Grid integrated with a PHP backend.
This review assumes a standard setup: a PHP script returning JSON data (Server-Side) or a PHP file rendering the HTML/JS (Client-Side).
You can use this as a checklist to review your own code, or paste your code in the next message for a specific review.
1. Endpoint: /api/grid-data (GET)
<?php header('Content-Type: application/json'); header('Access-Control-Allow-Origin: *');require_once 'db.php'; // PDO connection
$request = json_decode(file_get_contents('php://input'), true);
$startRow = $request['startRow'] ?? 0; $endRow = $request['endRow'] ?? 100; $sortModel = $request['sortModel'] ?? []; $filterModel = $request['filterModel'] ?? [];
$limit = $endRow - $startRow; $offset = $startRow;
// Base query $sql = "SELECT id, name, email, created_at FROM users WHERE 1=1"; $params = [];
// Apply filters foreach ($filterModel as $field => $filter) if ($filter['filterType'] === 'text') $sql .= " AND $field LIKE :$field"; $params[":$field"] = '%' . $filter['filter'] . '%';
// Apply sorting if (!empty($sortModel)) $orderBy = []; foreach ($sortModel as $sort) $orderBy[] = "$sort['colId'] $sort['sort']"; $sql .= " ORDER BY " . implode(', ', $orderBy);
// Get total row count $countSql = preg_replace('/SELECT.FROM/', 'SELECT COUNT() as total FROM', $sql, 1); $stmt = $pdo->prepare($countSql); $stmt->execute($params); $totalRows = $stmt->fetch(PDO::FETCH_ASSOC)['total'];
// Add pagination $sql .= " LIMIT $limit OFFSET $offset"; $stmt = $pdo->prepare($sql); $stmt->execute($params); $rows = $stmt->fetchAll(PDO::FETCH_ASSOC);
echo json_encode([ 'rows' => $rows, 'lastRow' => $totalRows ]);
3. PHP Backend API (Updated for AG Grid v31+)
AG Grid’s server-side row model requires specific request parameters. We’ll build a RESTful endpoint that handles:
- Sorting (
sortModel) - Filtering (
filterModel) - Pagination (
startRow,endRow) - Grouping (optional)
File: db.php (PDO connection)
<?php header('Content-Type: application/json'); header('Access-Control-Allow-Origin: *'); header('Access-Control-Allow-Methods: GET, POST, PUT, DELETE'); header('Access-Control-Allow-Headers: Content-Type');$host = 'localhost'; $dbname = 'aggrid_demo'; $user = 'root'; $pass = '';
try $pdo = new PDO("mysql:host=$host;dbname=$dbname;charset=utf8mb4", $user, $pass); $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); catch(PDOException $e) die(json_encode(['error' => 'Database connection failed'])); ?>
File: server.php (main API logic)
<?php require_once 'db.php';$request_method = $_SERVER['REQUEST_METHOD']; $input = json_decode(file_get_contents('php://input'), true);
// Handle GET request for grid data if ($request_method === 'GET' && isset($_GET['action']) && $_GET['action'] === 'getRows') // Extract AG Grid request parameters $startRow = isset($_GET['startRow']) ? (int)$_GET['startRow'] : 0; $endRow = isset($_GET['endRow']) ? (int)$_GET['endRow'] : 100; $limit = $endRow - $startRow;
$sortModel = isset($_GET['sortModel']) ? json_decode($_GET['sortModel'], true) : []; $filterModel = isset($_GET['filterModel']) ? json_decode($_GET['filterModel'], true) : []; // Base query $sql = "SELECT * FROM products"; $countSql = "SELECT COUNT(*) as total FROM products"; $params = []; // Build WHERE clause from filterModel $whereClauses = []; if (!empty($filterModel)) foreach ($filterModel as $field => $filter) if ($filter['filterType'] === 'text') $whereClauses[] = "$field LIKE :$field"; $params[":$field"] = '%' . $filter['filter'] . '%'; elseif ($filter['filterType'] === 'number') if (isset($filter['filter'])) $whereClauses[] = "$field = :$field_eq"; $params[":$field_eq"] = $filter['filter']; if (isset($filter['filterTo'])) $whereClauses[] = "$field <= :$field_to"; $params[":$field_to"] = $filter['filterTo']; if (!empty($whereClauses)) $whereStr = " WHERE " . implode(" AND ", $whereClauses); $sql .= $whereStr; $countSql .= $whereStr; // Build ORDER BY from sortModel if (!empty($sortModel)) $orderBy = []; foreach ($sortModel as $sort) $orderBy[] = "$sort['colId'] $sort['sort']"; $sql .= " ORDER BY " . implode(", ", $orderBy); // Add LIMIT for pagination $sql .= " LIMIT $startRow, $limit"; // Get total row count (without pagination) $totalStmt = $pdo->prepare($countSql); foreach ($params as $key => &$val) $totalStmt->bindParam($key, $val); $totalStmt->execute(); $totalRows = $totalStmt->fetch(PDO::FETCH_ASSOC)['total']; // Get paginated data $stmt = $pdo->prepare($sql); foreach ($params as $key => &$val) $stmt->bindParam($key, $val); $stmt->execute(); $rows = $stmt->fetchAll(PDO::FETCH_ASSOC); // Return AG Grid expected format echo json_encode([ 'success' => true, 'rows' => $rows, 'lastRow' => $totalRows ]); exit;// Handle POST to add a new row if ($request_method === 'POST' && isset($_GET['action']) && $_GET['action'] === 'addRow') $stmt = $pdo->prepare("INSERT INTO products (name, category, price, stock) VALUES (:name, :category, :price, :stock)"); $stmt->execute([ ':name' => $input['name'], ':category' => $input['category'], ':price' => $input['price'], ':stock' => $input['stock'] ]); echo json_encode(['success' => true, 'id' => $pdo->lastInsertId()]); exit;
// Handle PUT to update a row if ($request_method === 'PUT' && isset($_GET['action']) && $_GET['action'] === 'updateRow') $stmt = $pdo->prepare("UPDATE products SET name=:name, category=:category, price=:price, stock=:stock WHERE id=:id"); $stmt->execute([ ':id' => $input['id'], ':name' => $input['name'], ':category' => $input['category'], ':price' => $input['price'], ':stock' => $input['stock'] ]); echo json_encode(['success' => true]); exit; Integrating AG Grid with PHP allows you to
// Handle DELETE if ($request_method === 'DELETE' && isset($_GET['action']) && $_GET['action'] === 'deleteRow') $id = $_GET['id']; $stmt = $pdo->prepare("DELETE FROM products WHERE id = ?"); $stmt->execute([$id]); echo json_encode(['success' => true]); exit; ?>
4. Sorting and Filtering
- For small datasets (e.g., < 1,000 rows), you can let AG Grid handle sorting/filtering in the browser (Client-Side Model).
- For large datasets, the PHP file must read the
sortModelandfilterModelsent by AG Grid's Server-Side Row Model. In the PHP example above, I implemented a simplified manual check forGETparameters to demonstrate how to hook into SQLORDER BYclauses securely.