PHP Case Studies & Practical Application 5 — Questions and Answers
Question 1: You need to parse an XML feed from a third-party supplier in PHP. Which extension is preferred for reading large XML files without loading the entire document into memory?
- XMLReader (stream-based SAX-style parser) (Correct answer)
- SimpleXML
- DOMDocument
- json_decode after converting with simplexml_load_string
Correct answer: XMLReader (stream-based SAX-style parser)
XMLReader reads XML as a forward-only stream, processing nodes one at a time and keeping memory usage constant regardless of file size.
Question 2: A PHP application must prevent the same form from being submitted twice if the user clicks the submit button rapidly. What is the standard server-side solution?
- Generate a unique CSRF/nonce token per form, store it in the session, and invalidate it after first use (Correct answer)
- Disable the submit button with JavaScript after the first click
- Check the Referer header on form submission
- Use output buffering to delay the response
Correct answer: Generate a unique CSRF/nonce token per form, store it in the session, and invalidate it after first use
A one-time server-side nonce ensures duplicate submissions are rejected even if JavaScript is disabled or bypassed.
Question 3: Your PHP application uses Composer. A developer installs a package that pulls in a dependency with a known CVE. What is the correct way to detect this?
- Run composer audit to check installed packages against the PHP Security Advisories Database (Correct answer)
- Manually check each package's GitHub page
- Delete vendor/ and reinstall to get fresh copies
- Switch from Composer to manual downloads
Correct answer: Run composer audit to check installed packages against the PHP Security Advisories Database
composer audit queries the security advisories database and reports any installed package versions with known vulnerabilities.
Question 4: A multi-tenant PHP SaaS app stores all customers in one database with a tenant_id column. A query forgets to filter by tenant_id. What is the result?
- One tenant can read or modify another tenant's data (data leakage) (Correct answer)
- The query runs slower due to full table scans
- PHP throws a fatal error at runtime
- The database rejects the query with a foreign key error
Correct answer: One tenant can read or modify another tenant's data (data leakage)
Missing tenant isolation filters in a shared database architecture lead to cross-tenant data exposure, a critical security vulnerability.
Question 5: You refactor a PHP function to use type declarations. The function signature is `function total(int $qty, float $price): float`. What happens when it's called with total('3', '9.99')?
- In strict mode (declare(strict_types=1)), a TypeError is thrown; without strict mode, PHP coerces the strings to int and float (Correct answer)
- PHP throws a TypeError in all cases
- PHP silently ignores type declarations at runtime
- The function returns null
Correct answer: In strict mode (declare(strict_types=1)), a TypeError is thrown; without strict mode, PHP coerces the strings to int and float
PHP's type coercion applies in weak mode, but declare(strict_types=1) disables coercion and enforces exact types, throwing a TypeError on mismatch.
Question 6: A PHP developer wants to test a class that sends HTTP requests to an external API. What technique allows testing without making real network calls?
- Inject a mock HTTP client implementing the same interface and return pre-configured responses in tests (Correct answer)
- Use file_get_contents() instead of cURL in production
- Add a test flag to the class that skips the HTTP call
- Record all real API responses to a log file and replay them
Correct answer: Inject a mock HTTP client implementing the same interface and return pre-configured responses in tests
Dependency injection with a mock client allows full control over HTTP responses in tests, making tests fast, deterministic, and offline-capable.
Question 7: A PHP application's homepage is slow because it aggregates data from five database queries on every load. The data changes only once per hour. What is the best optimization?
- Cache the aggregated result with a 1-hour TTL using Redis or APCu (Correct answer)
- Add indexes to all five tables
- Move the queries to a stored procedure
- Run the queries asynchronously using AJAX
Correct answer: Cache the aggregated result with a 1-hour TTL using Redis or APCu
Caching the pre-aggregated result eliminates all five queries on each request, reducing response time to a single cache lookup for the TTL duration.
You need to parse an XML feed from a third-party supplier in PHP.
Which extension is preferred for reading large XML files without loading the entire document into memory?