Abdul Rehman
Abdul Rehman Portfolio Loader Image Abdul Rehman Portfolio Loader Image Abdul Rehman Portfolio Loader Image Abdul Rehman Portfolio Loader Image Abdul Rehman Portfolio Loader Image Abdul Rehman Portfolio Loader Image Abdul Rehman Portfolio Loader Image
0 %
Loading

How I Built Dehari: A Home Services Platform

A case study on building a home services platform with a PHP web app, Java recommendation engine, and the hard lessons I picked up along the way.

June 27, 2026 Case Study
PHP Java REST API MySQL

Dehari started as a semester project. My team and I wanted to build something that solved a real problem in Karachi, not just another CRUD app to pass a class. The idea was simple: connect people who need home services (electricians, plumbers, cleaners) with local professionals they can actually trust. The execution turned out to be anything but simple.

I want to walk through how I built this home services platform, the architecture decisions that worked, the ones that did not, and what I would change if I started over today.

The Problem We Were Solving

Finding a reliable electrician or plumber in Karachi is a word-of-mouth process. You ask your neighbor, your cousin, or the building watchman. If none of them know someone, you scroll through random listings and hope for the best. There is no centralized way to compare providers, check reviews, or book a time slot.

We wanted Dehari to fix that. A user should be able to open the platform, pick a service category, see available providers ranked by relevance, and book one in under two minutes. Providers should have profiles with ratings, completed job counts, and verified information. An admin dashboard should let platform operators manage the whole ecosystem.

Three audiences, three different interfaces, one shared database. That constraint shaped every technical decision we made.

Why PHP and Java Together

This is the question I get asked most. PHP and Java are not a natural pairing. Most teams pick one or the other. We used both because the project had two distinct requirements that called for different tools.

The web application (user-facing booking flow, provider profiles, admin dashboard) needed to be built fast. PHP with MySQL was the obvious choice for our team. We knew the language well, the deployment story is straightforward, and Bootstrap gave us a responsive frontend without burning time on custom component libraries.

The recommendation engine was a different beast. We needed to process user behavior data, compute similarity scores between users, and generate ranked provider lists. Java gave us better data structure support for this kind of computation. The java.util collections library, strong typing, and the ability to run the engine as a standalone service all made Java the better fit for that module.

The PHP Java integration happened through REST APIs. The Java recommendation engine ran as a separate process with its own HTTP endpoints. When the PHP app needed recommendations for a user, it made a cURL request to the Java service, got back a JSON response, and rendered the results. Clean separation. Each piece could be developed and tested independently.

Building the Recommendation Engine

The recommendation engine used collaborative filtering. The basic idea: if User A and User B both booked the same three plumbers and rated them similarly, and User B also booked a fourth plumber that User A has not tried, then that fourth plumber is probably a good recommendation for User A.

I implemented this using a user-item matrix stored in MySQL. Each row was a user, each column was a service provider, and each cell held a rating (1 to 5) or was empty. The Java service read this matrix on startup, computed cosine similarity between user vectors, and cached the results.

When the PHP app requested recommendations for a given user ID, the Java service would:

  1. Look up the target user's ratings vector
  2. Find the top 10 most similar users by cosine similarity
  3. Collect providers those similar users rated highly but the target user had not booked
  4. Score and rank those providers
  5. Return the top results as JSON

The cold start problem was real. New users with no booking history got no personalized recommendations. We handled this with a fallback: if the engine returned an empty set, the PHP app would show providers sorted by average rating and number of completed bookings instead. Not elegant, but functional.

One mistake I made early on was recomputing the similarity matrix on every request. With 50 test users this was fine. With 500 it became slow. I added a caching layer that recomputed the matrix every 30 minutes instead of on every API call. Response times dropped from around 800ms to under 100ms.

The Database Design

I spent more time on the MySQL schema than on any other part of the project. The core tables were:

  • users with role-based flags (customer, provider, admin)
  • providers linked to users with additional fields for service area, hourly rate, and verification status
  • services for category definitions (electrical, plumbing, cleaning, etc.)
  • bookings tracking status (pending, confirmed, completed, cancelled), timestamps, and payment info
  • reviews with ratings, text, and foreign keys to both the booking and the provider
  • recommendations_cache storing precomputed results from the Java engine

I used foreign key constraints everywhere. This caught bugs early. If a piece of PHP code tried to insert a booking for a nonexistent provider, MySQL would reject it immediately instead of letting bad data accumulate silently.

The bookings table went through three redesigns. The first version was too flat. It stored the provider's name and rate directly instead of referencing the provider table. That meant if a provider updated their rate, old bookings would show the wrong information. The final version used proper foreign keys and stored a snapshot of the rate at booking time in a separate booking_details column.

The Admin Dashboard

The admin dashboard was built entirely in PHP with Bootstrap. It gave platform operators the ability to:

  • View and manage all users and providers
  • Approve or reject provider verification requests
  • Monitor booking volume and cancellation rates
  • Handle dispute resolution between customers and providers
  • View platform-wide analytics (daily bookings, revenue, top providers)

I built the analytics section using raw SQL aggregation queries. No charting library on the backend. The PHP code ran queries like SELECT DATE(created_at), COUNT(*) FROM bookings GROUP BY DATE(created_at) and passed the results to a JavaScript charting library on the frontend. This kept the backend simple and let me swap charting libraries without touching server code.

Role-based access control used PHP sessions with a role check on every admin page load. If the session's role was not "admin", the page redirected to the login screen. I stored hashed passwords using PHP's password_hash() with bcrypt. No plaintext passwords anywhere.

The REST API Layer

The API between PHP and Java was minimal. Three endpoints:

  • GET /recommendations/{userId} returned ranked provider suggestions
  • POST /ratings accepted new rating data to update the matrix
  • GET /health let the PHP app check if the Java service was running

I kept it to three endpoints on purpose. Every additional endpoint is a contract you have to maintain across two codebases in two languages. When the Java service was down (which happened more than I would like to admit during development), the PHP app needed to degrade gracefully. That health check endpoint let me build a simple circuit breaker: if three consecutive health checks failed, the PHP app would stop calling the recommendation endpoint and fall back to the rating-based sort until the next successful health check.

Error handling across the API boundary was tricky. The Java service returned HTTP status codes, but the error messages were sometimes in a different format than what the PHP app expected. I standardized on a simple JSON error format: {"error": true, "message": "description"}. Both sides agreed on this contract, and debugging got much easier after that.

What I Got Wrong

Plenty of things. The biggest mistake was not writing tests early. I wrote the first 3,000 lines of PHP without a single test. When I finally added tests, I found bugs that had been hiding for weeks. A booking confirmation email was being sent even when the booking failed validation. A provider search query was returning inactive providers. These would have been caught immediately with basic unit tests.

Another mistake was the deployment setup. During development, the PHP app and Java service ran on the same machine. I did not think about what would happen if they needed to be on separate servers. The Java service URL was hardcoded in four different PHP files. When I eventually needed to change it, I had to hunt down every occurrence. A config file or environment variable would have taken five minutes to set up and saved me an hour of debugging later.

The frontend code was also too tightly coupled to the backend. I embedded PHP variables directly in JavaScript blocks. This made the code hard to read and impossible to cache on the client side. If I were rebuilding Dehari today, I would use a proper API-first approach where the frontend is a separate JavaScript application consuming a PHP REST API.

What I Got Right

The separation between the web app and the recommendation engine paid off immediately. My teammate could work on the Java recommendation logic while I built the PHP booking flow. We did not step on each other's code. We agreed on the API contract early and worked independently until integration day.

The database design, after those three iterations, was solid. Foreign keys prevented data corruption. Proper indexing on the bookings table (indexed on provider_id, user_id, and status) kept queries fast even as test data grew.

Using Bootstrap for the frontend saved significant time. The admin dashboard looked professional without custom CSS work, and responsive behavior came for free. For an academic project with a fixed deadline, that tradeoff made sense.

Lessons for Web Application Development

Building Dehari taught me things I could not have learned from tutorials. A few that stuck with me:

Start with the database schema. If your data model is wrong, every layer above it will be wrong too. I spent what felt like too long on the MySQL schema, but it turned out to be the right investment.

Keep cross-language integrations minimal. The PHP Java integration worked because the API surface was tiny. Three endpoints. If we had built 20, the maintenance burden would have been unsustainable for a small team.

Build the fallback before you build the feature. The recommendation engine's fallback (sort by rating) was simple but it meant the platform was never broken, even when the Java service crashed. Users always saw providers. The quality of recommendations varied, but the page always loaded.

Do not optimize until you measure. My first instinct was to add Redis caching, connection pooling, and query optimization everywhere. The reality was that a simple in-memory cache on the Java side and proper MySQL indexes on the PHP side handled our load without any additional infrastructure.

Dehari is still one of the projects I am most proud of. It was the first time I built something with multiple services talking to each other across language boundaries, and it worked. Not perfectly. But it worked. And every project I have built since has been better because of what I learned on this one.

If you are working on your own home services platform or any multi-service web application, I am happy to talk through architecture decisions. You can reach me through the contact page or check out the full Dehari project page for screenshots and technical details.

OneCinfinity - marketing agency
OneCinfinity - marketing agency
Baby Bloom Shop Mobile App
Dehari - home based services
Dehari - home based services
Fun Spot Park
Laundry Management System
Laundry Management System
Rhythm Rang - web app
Rhythm Rang - web app
Dehari - home based services
Baby Bloom Shop - mobile app
Fun Spot Park
Laundry Management System
Rhythm Rang - web app