PHP / Basic: values and request foundations / Lesson 1
PHP execution, values, and the runtime boundary
Understand how a PHP program runs before connecting it to a web request. Use a PHP 8.3 syntax baseline and distinguish the validated PHP 8.5 CLI host from a web server process.
On this page
Lesson goals
- Separate CLI execution from HTTP request handling.
- Identify values, variables, and explicit conversions.
- State version and extension assumptions.
One language, several execution interfaces
PHP code can run as a command-line program or inside a server interface that handles HTTP requests. The language rules are shared, but input sources, output handling, extensions, and process lifetime differ. A CLI argument is not automatically a form value, and echo in a shell does not demonstrate a browser response header. This course uses PHP 8.3-compatible syntax unless a later feature is explicitly labeled. Complete examples were checked on PHP 8.5.12 CLI; that validation does not claim execution on every supported branch or on a configured production application.
Values have types; variable names communicate intent
PHP values include integers, floating-point numbers, strings, booleans, arrays, objects, null, and resource values supplied by particular APIs. A variable name begins with a dollar sign and can later refer to a different value, although unnecessary type changes make reasoning harder. Use names such as quantityText and quantity to make a parsing boundary visible. Numeric-looking text is still text until conversion or an operation applies its rules. Keep money examples in integer minor units to avoid confusing binary floating-point representation with a complete financial rounding policy.
<?php
declare(strict_types=1);
$quantityText = "3";
$quantity = (int) $quantityText;
$unitCents = 250;
echo get_debug_type($quantityText), " ", get_debug_type($quantity), PHP_EOL;
echo $quantity * $unitCents, PHP_EOL;
string int
750
The cast demonstrates conversion only. A real input boundary must reject malformed or out-of-range quantities before using the result.
Strict types does not validate a request
declare(strict_types=1) affects scalar type handling at relevant call boundaries in that file. It does not transform all external input into valid domain values or turn PHP into a statically typed language. A string request parameter still needs parsing, and arrays still need field validation. Internal functions and special coercion cases have their own documented rules. Prefer explicit contracts over assuming a single directive eliminates ambiguity. A typed function can protect its narrow boundary while the caller remains responsible for interpreting missing, malformed, and culturally formatted user input correctly.
Assignment differs for arrays and objects
PHP arrays have value semantics with implementation optimizations such as copy-on-write, while assigning an object variable copies the handle to the same object. Mutating an object through one variable is therefore visible through another handle. An array containing objects can still share those objects even after the outer array is assigned elsewhere. References created with an ampersand introduce another aliasing mechanism and should be used deliberately. Explain the ownership model before editing a draft record; a cheap-looking assignment does not automatically isolate every nested object or external resource.
<?php
declare(strict_types=1);
$original = ["seats" => 2];
$draft = $original;
$draft["seats"] = 1;
$object = (object) ["seats" => 2];
$alias = $object;
$alias->seats = 1;
echo $original["seats"], " ", $draft["seats"], PHP_EOL;
echo $object->seats, PHP_EOL;
2 1
1
The top-level arrays separate on modification; the two object variables still reach the same object.
Record the environment without exposing configuration
Use php -v and targeted extension checks in a local environment rather than publishing a full phpinfo page. A missing PDO driver is an environment capability issue, not necessarily a syntax defect. Keep examples self-contained and use temporary storage or sqlite::memory: only where a database is needed. Do not copy a configured application DSN into a learning exercise. Track the runtime, enabled extensions, and expected output with the example. Version support is a maintained external fact: consult the official support schedule when planning an upgrade rather than treating this courseโs baseline as a deployment recommendation.
Common errors and fixes
A CLI print is treated as an HTTP test
- Why it happens
- Execution interface differences are ignored.
- How to fix it
- Label CLI evidence and test HTTP separately in an isolated setup.
- Prevent it next time
- State input and output channels for each example.
An integer cast is accepted as validation
- Why it happens
- Malformed text can be converted to a misleading number.
- How to fix it
- Validate format and range before domain arithmetic.
- Prevent it next time
- Test missing, empty, malformed, and boundary inputs.
A draft unexpectedly edits an object elsewhere
- Why it happens
- Object-handle sharing is mistaken for a deep copy.
- How to fix it
- Define ownership and copy the required object graph deliberately.
- Prevent it next time
- Review nested objects and explicit references during updates.
Check your understanding
1. What does strict_types add, and what does it not establish?
Show worked solution
It changes relevant scalar argument handling for calls from that file. It does not validate a request schema, check allowed quantities, sanitize output, or prove authorization. Keep those boundaries explicit and test them independently using synthetic data.
2. A course example requires PDO SQLite. How do you isolate it?
Show worked solution
Check the local SQLite PDO driver, create a new PDO("sqlite::memory:") inside the example, and seed only synthetic rows. Never load the application connection settings. Record the actual PHP version and driver used; passing this example does not validate another database engineโs behavior.
Key takeaways
- Separate language rules from host and deployment assumptions.
- Types, parsing, and ownership are distinct contracts.