💡 : 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.
); const api = agGrid.createGrid(gridDiv, gridOptions); // Fetch data from PHP backend const datasource = getRows: (params) => fetch( 'datasource.php' , method:</p> aggrid php example updated
This article provides a comprehensive, updated guide and example for implementing AG Grid with a PHP backend as of 2026, focusing on modern best practices. 1. Why Use AG Grid with PHP? 💡 : Use a prepared statement or an
AppFactory::setContainer($container); $app = AppFactory::create(); Why Use AG Grid with PHP
npm install ag-grid-community
// 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();
PDO::ERRMODE_EXCEPTION, PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, PDO::ATTR_EMULATE_PREPARES => false, ]); catch (PDOException $exception) echo json_encode(["error" => "Database connection failed: " . $exception->getMessage()]); exit; // 2. Parse AG Grid Request Payload $input = json_decode(file_get_contents("php://input"), true); $startRow = isset($input['startRow']) ? (int)$input['startRow'] : 0; $endRow = isset($input['endRow']) ? (int)$input['endRow'] : 100; $pageSize = $endRow - $startRow; $sortModel = isset($input['sortModel']) ? $input['sortModel'] : []; $filterModel = isset($input['filterModel']) ? $input['filterModel'] : []; // 3. Build Base Queries $whereClauses = []; $params = []; // Whitelist of columns to prevent SQL injection during dynamic sorting $allowedColumns = ['id', 'name', 'role', 'department', 'salary', 'join_date']; // 4. Handle Server-Side Filtering if (!empty($filterModel)) foreach ($filterModel as $column => $filterData) if (!in_array($column, $allowedColumns)) continue; $filterType = $filterData['filterType'] ?? ''; $type = $filterData['type'] ?? ''; $filterText = $filterData['filter'] ?? ''; if ($filterType === 'text') if ($type === 'contains') $whereClauses[] = "`$column` LIKE :filter_$column"; $params["filter_$column"] = "%" . $filterText . "%"; elseif ($type === 'equals') $whereClauses[] = "`$column` = :filter_$column"; $params["filter_$column"] = $filterText; elseif ($filterType === 'number') if ($type === 'equals') $whereClauses[] = "`$column` = :filter_$column"; $params["filter_$column"] = $filterText; elseif ($type === 'greaterThan') $whereClauses[] = "`$column` > :filter_$column"; $params["filter_$column"] = $filterText; $whereSql = ''; if (!empty($whereClauses)) $whereSql = ' WHERE ' . implode(' AND ', $whereClauses); // 5. Get Total Row Count Matching Filters $countSql = "SELECT COUNT(*) FROM employees" . $whereSql; $countStmt = $pdo->prepare($countSql); $countStmt->execute($params); $totalRows = (int)$countStmt->fetchColumn(); // 6. Handle Server-Side Sorting $sortSql = ''; if (!empty($sortModel)) $sortParts = []; foreach ($sortModel as $sort) $colId = $sort['colId']; $direction = strtoupper($sort['sort']) === 'DESC' ? 'DESC' : 'ASC'; if (in_array($colId, $allowedColumns)) $sortParts[] = "`$colId` $direction"; if (!empty($sortParts)) $sortSql = ' ORDER BY ' . implode(', ', $sortParts); // 7. Handle Pagination Limit Clauses $limitSql = " LIMIT :limit OFFSET :offset"; // 8. Execute Final Data Fetch Query $dataSql = "SELECT * FROM employees" . $whereSql . $sortSql . $limitSql; $dataStmt = $pdo->prepare($dataSql); // Bind bindValue explicitly to enforce integers for LIMIT/OFFSET foreach ($params as $key => $value) $dataStmt->bindValue($key, $value); $dataStmt->bindValue(':limit', $pageSize, PDO::PARAM_INT); $dataStmt->bindValue(':offset', $startRow, PDO::PARAM_INT); $dataStmt->execute(); $rows = $dataStmt->fetchAll(); // 9. Send Standard AG Grid Response echo json_encode([ "rows" => $rows, "totalRows" => $totalRows ]); Use code with caution. 3. The Frontend ( index.html )

WARNING The following website, including all webpages, links, images and videos, display sexually explicit material. Only consenting adults are authorized beyond this page. If you are a minor (under the age of 18 years old or 21 years old where 18 isn't the legal age of majority), if sexually explicit material offends you or if it's illegal to view such material in your community, or if you disagree with the following statements in any way, you MUST leave by clicking EXIT below. By ENTERING this site, you irrevocably agree to these statements: You are an adult in your community and are at least 18 years old (21 in those communities where required). You will not expose, or allow others to expose minors to the sexually explicit content contained on this website. You believe that sexually explicit material is not offensive or obscene, and affirm that sexually explicit material is not deemed to be obscene or illegal in the community in which you will view these materials. You further affirm that you wish to view such materials and that no other person has coerced you into doing so. You will use the material available on this website for your own personal use and will not sell, distribute, give or make available the content on this website to anyone. You will take the appropriate steps in order to make sure no minor is able to view the content available on this site. You understand that if you disagree with any of the prior statements, you are not permitted to enter this website and to view its contents. By entering this website, you acknowledge that you have read this agreement, understood it and agree to be bound by it.