Keyword search can miss records that describe the same problem using different words. In this tutorial, we will add semantic search to a PHPRunner support-ticket application. A search for ‘customers having access or login problems’ can find tickets about rejected credentials, unauthorized sessions, or account access even when they do not contain the exact search phrase.

The application uses the OpenAI Embeddings API to convert ticket text and each search phrase into vectors. PHPRunner then compares those vectors locally with cosine similarity and returns the 30 closest tickets. This approach is intended for relatively small collections. For tens of thousands of records or more, use a vector database instead of comparing every vector in PHP. The cosine similarity scores in the diagram measure how closely the vectors are related. They are not probabilities or percentages of correctness.

Continue Reading "Add Semantic Search to a PHPRunner Application" →

Employees often need to complete onboarding, safety, or compliance videos. In this tutorial, we will build a training video tracker that resumes each video from the saved position, allows rewinding, prevents users from skipping unwatched sections, and records completion.

The same approach works in PHPRunner and ASPRunner.NET. The browser-side code is the same in both products, while the server-side examples are provided separately in PHP and C#.

Continue Reading "Track Employee Training Video Completion" →

Equipment checkout applications need to do more than store a list of assets. The application should prevent duplicate checkouts, show only actions that match the current asset status, record returns, flag overdue equipment, and let staff find an item quickly.

In this tutorial, we will build that workflow in PHPRunner or ASPRunner.NET and add camera-based QR code scanning. The JavaScript is the same in both products. Server events are provided in PHP and C#.

Continue Reading "Build an Equipment Checkout System with QR Code Scanning" →

Exporting hundreds of thousands of records during a normal page request can exceed PHP execution limits and leave the user waiting without any indication of progress.

This PHPRunner tutorial moves large CSV exports into a scheduled worker. Users submit an export request, the worker processes a fixed number of records per run, and the List page shows progress until the ZIP file is ready to download.

Continue Reading "Process Large CSV Exports in Background Batches" →

The Model Context Protocol, or MCP, provides a standard way for AI assistants to connect to applications, discover available tools, and work with live data.

We created an early MCP prototype to explore how this technology could work inside a generated PHPRunner application.

Watch the PHPRunner MCP demonstration on YouTube

Download the PHPRunner MCP sample project

Continue Reading "Experimenting with MCP Support in PHPRunner" →

List pages often contain several actions for every record. Displaying each action as a separate button can make the grid unnecessarily wide, especially on smaller screens.

In this tutorial, we will add one menu button to each grid row. The menu will open View, Edit, Copy, and related-record pages, process Delete with confirmation, and include an Archive placeholder for project-specific code. The same approach works in PHPRunner and ASPRunner.NET.

Custom row actions menu on a data grid

Continue Reading "Add a Custom Row Actions Menu to a Data Grid" →

PHPRunner and ASPRunner.NET dashboards can display several grids on one page. In this tutorial, we will add a separate search box to each grid so users can filter Customers, Products, or Employees without affecting the other dashboard elements.

The solution uses one reusable JavaScript function and a small amount of Custom CSS. The same code works in PHPRunner and ASPRunner.NET.

Continue Reading "Add Search Boxes to Individual Dashboard Grids" →

PHPRunner and ASPRunner.NET already provide password policies, encrypted password storage, CAPTCHA, two-factor authentication, and user permissions. In this tutorial, we will add two more checks: reject passwords found in known data breaches and block visitors whose IP addresses have a very high abuse score.

During registration, haveibeenpwned.com checks whether the password has appeared in known data breaches. The password itself is never sent to the service, and this API does not require a key.

Before processing an application page, abuseipdb.com checks whether the visitor’s IP address has been associated with abusive activity. This service requires an API key. Section 6 explains how to create that key. The results are cached locally to reduce the number of external requests.

Continue Reading "Block Compromised Passwords and High-Risk IP Addresses" →

The World Cup 2026 Crystal Ball Challenge is over! Thank you to everyone who took part and made the challenge fun and engaging. Congratulations to all participants, and especially to the winners for their outstanding predictions!

In this tutorial we will cover all non-trivial techniques that made this project possible. As you can imagine, the main challenge making this project look sleek and easy to use and I believe we achieved this goal.

See the final leaderboard online

We will talk about:

1. Creating image-based edit controls
2. Grouping team pickers and preventing duplicate selections
3. Enforcing one prediction per user with PHPRunner events
4. Disabling Add and Edit after the submission deadline
5. Enabling Save only after all required answers are selected
6. Calculating scores and rankings with custom SQL
7. Adding rank graphics, progress bars, and current-user highlighting
8. Integrating custom landing, scoring, and thank-you pages
9. A few more visual tweaks
10. How to create your own custom Edit controls easily

Continue Reading "Building a World Cup Prediction Challenge in PHPRunner" →