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: ; aggrid php example updated
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); Building a High-Performance Data Grid: AG Grid &
$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?
This is the "Updated" part. We use modern AG Grid syntax, enabling Enterprise-style features (like editing) using the Community version. , // Enables SSRM pagination: true, paginationPageSize: ,
File: index.html
<!DOCTYPE html>
<html lang="en">
<head>
<title>AG Grid PHP Updated Example</title>
<!-- Ag-Grid CSS -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ag-grid-community/styles/ag-grid.css"/>
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ag-grid-community/styles/ag-theme-alpine.css"/>
<style>
#myGrid height: 500px; width: 100%;
</style>
</head>
<body>
<div id="myGrid" class="ag-theme-alpine"></div>
<!-- Ag-Grid JS -->
<script src="https://cdn.jsdelivr.net/npm/ag-grid-community/dist/ag-grid-community.min.js"></script>
<script>
// Define Column Definitions
const columnDefs = [
field: 'id', hide: true , // ID is hidden but needed for updates
field: 'employee_name', filter: true, editable: true ,
field: 'job_title', editable: true ,
field: 'department', filter: true, editable: true ,
field: 'salary',
editable: true,
valueFormatter: params => '$' + params.value.toLocaleString(),
filter: 'agNumberColumnFilter'
];
// Grid Options
const gridOptions =
columnDefs: columnDefs,
rowData: null, // Start empty
defaultColDef:
flex: 1,
minWidth: 100,
sortable: true
,
// Enable editing
editType: 'fullRow', // Edit whole row at once
onRowValueChanged: onRowValueChanged // Event listener for saves
;
// Initialize Grid
document.addEventListener('DOMContentLoaded', () =>
const gridDiv = document.querySelector('#myGrid');
new agGrid.Grid(gridDiv, gridOptions);
// Fetch initial data
fetchGridData();
);
// Function to fetch data from PHP
function fetchGridData()
// Example: Add sorting params if needed manually, or use AG Grid datasource
fetch('api.php?action=fetch')
.then(response => response.json())
.then(data =>
gridOptions.api.setRowData(data); // Updated API method
)
.catch(err => console.error('Error fetching data:', err));
// Function to handle data update (Backend Sync)
function onRowValueChanged(event)
const newData = event.data;
console.log('Saving changes:', newData);
fetch('api.php?action=update',
method: 'POST',
headers: 'Content-Type': 'application/json' ,
body: JSON.stringify(newData)
)
.then(response => response.json())
.then(res =>
if (res.success)
console.log('Database updated successfully');
// Optional: Show a toast notification
else
alert('Error updating database: ' + res.message);
// Optional: Revert the grid change
);
</script>
</body>
</html>
Create a project folder: aggrid-php-example/. Inside, create index.html (or index.php), server.php, and db.php.
Required tools:
Include AG Grid in your HTML (updated to v31.3.2):
<!-- index.html -->
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ag-grid-community/styles/ag-grid.css">
<link rel="stylesheet" href="https://cdn.jsdelivr.net/npm/ag-grid-community/styles/ag-theme-alpine.css">
<script src="https://cdn.jsdelivr.net/npm/ag-grid-community/dist/ag-grid-community.min.js"></script>
sortModel and filterModel to avoid dangerous SQLCreate a MySQL database and add a table with some sample data. For this example, we'll use a simple table called "employees" with the following columns:
| id | name | email | department | | --- | --- | --- | --- | | 1 | John Smith | john.smith@example.com | Sales | | 2 | Jane Doe | jane.doe@example.com | Marketing| | 3 | Bob Brown | bob.brown@example.com | IT |