00: Setup & First Comparison

Chapter 0: Setup & First Comparison
Section titled “Chapter 0: Setup & First Comparison”Overview
Section titled “Overview”Welcome to PHP! As a Java developer, you’re already familiar with setting up development environments, compilers, and IDEs. PHP’s setup is refreshingly simple compared to Java - no need for complex build tools or JVM configuration. In this chapter, we’ll get you up and running with PHP and write your first script, comparing it side-by-side with Java code you already know.
By the end of this chapter, you’ll have a working PHP environment and understand the fundamental differences between PHP and Java execution models.
Prerequisites
Section titled “Prerequisites”Before starting this chapter, you should have:
- A computer running Windows, macOS, or Linux
- Administrator/sudo access to install software
- Your favorite text editor or IDE (we’ll show you how to configure it)
- Basic command line familiarity (you already have this!)
Estimated Time: ~45-60 minutes
What You’ll Build
Section titled “What You’ll Build”In this chapter, you’ll:
- Install PHP 8.4 (the latest stable version)
- Configure your IDE for PHP development
- Write a “Hello, World!” program in both Java and PHP
- Create a simple REST API endpoint in both languages
- Run PHP scripts from command line and web server
Quick Start
Section titled “Quick Start”If you’re already familiar with command-line tools and want to get up and running quickly:
# macOS (with Homebrew)brew install php@8.4
# Verify installationphp --version
# Create your first PHP scriptecho '<?php echo "Hello, PHP!";' > hello.php
# Run itphp hello.phpFor detailed setup instructions and comparisons with Java, continue reading below.
Objectives
Section titled “Objectives”By the end of this chapter, you’ll be able to:
- Install and configure PHP on your development machine
- Run PHP scripts from the command line and browser
- Compare Java and PHP execution models
- Understand key differences in syntax and structure
- Set up your IDE for productive PHP development
Step 1: Understanding PHP’s Execution Model (~10 min)
Section titled “Step 1: Understanding PHP’s Execution Model (~10 min)”Understand how PHP execution differs from Java’s compiled, JVM-based approach.
Java vs PHP: Key Differences
Section titled “Java vs PHP: Key Differences”Java’s Execution Model:
.java file → javac → .class file → JVM → Execution(Source) (Compile) (Bytecode) (Runtime) (Output)PHP’s Execution Model:
.php file → PHP Interpreter → Execution(Source) (Parse + Execute) (Output)Key Differences to Know
Section titled “Key Differences to Know”| Aspect | Java | PHP |
|---|---|---|
| Compilation | Compiled to bytecode | Interpreted (with opcache) |
| Execution | Runs in JVM | Native execution via PHP runtime |
| Deployment | JAR/WAR files | Source files directly |
| Startup | Application server (long-running) | Request-based (typically) |
| Reload | Restart required | Changes reflected immediately |
| Performance | JIT compilation, warm-up | Opcache + JIT (PHP 8+) |
::: tip Quick Comparison Think of PHP more like interpreted Python or Ruby, but with optional static typing (as of PHP 7.4+). Modern PHP has JIT compilation, making it surprisingly fast for most web applications. :::
Why It Matters
Section titled “Why It Matters”This execution model difference affects:
- Development workflow: PHP changes appear immediately (no compilation step)
- Deployment: You typically deploy source code, not compiled artifacts
- Memory management: PHP has request-based lifecycle, garbage collection per request
- State management: PHP is typically stateless between requests (unlike Spring Boot applications)
Step 2: Installing PHP (~15 min)
Section titled “Step 2: Installing PHP (~15 min)”Install PHP 8.4 on your development machine.
Actions
Section titled “Actions”::: code-group
# Install Homebrew if you don't have it/bin/bash -c "$(curl -fsSL https://raw.githubusercontent.com/Homebrew/install/HEAD/install.sh)"
# Install PHP 8.4brew install php@8.4
# Verify installationphp --version
# Should output: PHP 8.4.x (cli)...# Update package listssudo apt update
# Add PHP repositorysudo apt install software-properties-commonsudo add-apt-repository ppa:ondrej/php
# Install PHP 8.4sudo apt install php8.4 php8.4-cli php8.4-common php8.4-mbstring php8.4-xml php8.4-curl
# Verify installationphp --version# Option 1: Using Chocolateychoco install php --version=8.4
# Option 2: Download from windows.php.net# 1. Visit https://windows.php.net/download/# 2. Download "Thread Safe" ZIP for PHP 8.4# 3. Extract to C:\php# 4. Add C:\php to your PATH
# Verify installationphp --version# Enable REMI repositorysudo dnf install https://rpms.remirepo.net/fedora/remi-release-XX.rpm
# Install PHP 8.4sudo dnf module reset phpsudo dnf module install php:remi-8.4
# Verify installationphp --version:::
Expected Result
Section titled “Expected Result”Running php --version should display:
PHP 8.4.x (cli) (built: ...)Copyright (c) The PHP GroupZend Engine v4.4.x, Copyright (c) Zend Technologies with Zend OPcache v8.4.x, Copyright (c), by Zend Technologies::: tip OPcache If you see “with Zend OPcache” in the output, great! OPcache is PHP’s bytecode cache, similar to JVM’s JIT compilation. It significantly improves performance. :::
Why It Works
Section titled “Why It Works”PHP’s installation includes:
- PHP CLI: Command-line interpreter (like
javacommand) - PHP Libraries: Core extensions (similar to Java’s standard library)
- OPcache: Bytecode cache for performance
- Built-in web server: For local development (like Spring Boot’s embedded server)
Troubleshooting
Section titled “Troubleshooting”Problem: php: command not found
- Solution: PHP isn’t in your PATH. Find where PHP was installed and add it to your PATH.
Terminal window # Find PHP locationwhich php # macOS/Linuxwhere php # Windows# Add to PATH (add to ~/.bashrc or ~/.zshrc)export PATH="/usr/local/bin/php:$PATH"
Problem: Wrong PHP version
- Solution: Multiple PHP versions installed. Specify the version:
Terminal window # macOS with Homebrewbrew unlink php@8.3 && brew link php@8.4
Problem: Missing extensions
- Solution: Install required extensions:
Terminal window # Ubuntu/Debiansudo apt install php8.4-<extension-name># macOSpecl install <extension-name>
Step 2.5: Docker Installation (Alternative) (~5 min)
Section titled “Step 2.5: Docker Installation (Alternative) (~5 min)”Use Docker for a consistent PHP environment across all platforms.
Why Docker?
Section titled “Why Docker?”As a Java developer, you might already be familiar with Docker. Using Docker for PHP provides:
- Consistency: Same environment on all machines
- Isolation: No conflicts with system PHP
- Easy version switching: Run multiple PHP versions
- Pre-configured: Many images include common extensions
Quick Docker Setup
Section titled “Quick Docker Setup”# Pull official PHP imagedocker pull php:8.4-cli
# Run PHP in Dockerdocker run --rm php:8.4-cli php --version
# Run a PHP scriptdocker run --rm -v $(pwd):/app php:8.4-cli php /app/hello.php
# Interactive PHP shelldocker run --rm -it php:8.4-cli php -aDocker Compose for Development
Section titled “Docker Compose for Development”Create docker-compose.yml:
version: '3.8'services: php: image: php:8.4-apache ports: - "8000:80" volumes: - ./:/var/www/html environment: - PHP_INI_SCAN_DIR=/usr/local/etc/php/conf.dRun with:
docker-compose up# Access at http://localhost:8000::: tip Docker vs Native Use Docker if:
- You want isolated environments
- You switch between PHP versions often
- You work on multiple machines
Use Native if:
- You prefer direct system integration
- You want IDE autocomplete to work seamlessly
- You’re doing performance-critical development :::
Step 2.6: Installing Composer (~5 min)
Section titled “Step 2.6: Installing Composer (~5 min)”Install Composer, PHP’s dependency manager (like Maven/Gradle).
Installation
Section titled “Installation”::: code-group
# Download and install globallyphp -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"php composer-setup.phpphp -r "unlink('composer-setup.php');"sudo mv composer.phar /usr/local/bin/composer
# Verify installationcomposer --version# Download and run Composer-Setup.exe from:# https://getcomposer.org/Composer-Setup.exe
# After installation, verify:composer --version# Use Composer Docker imagedocker run --rm -v $(pwd):/app composer:latest --version
# Alias for convenience (add to ~/.bashrc or ~/.zshrc)alias composer='docker run --rm -v $(pwd):/app composer:latest':::
Why Composer?
Section titled “Why Composer?”| Java Tool | PHP Equivalent | Purpose |
|---|---|---|
| Maven | Composer | Dependency management |
| pom.xml | composer.json | Project configuration |
| mvn install | composer install | Install dependencies |
| .m2/repository | vendor/ | Dependencies location |
Test Composer
Section titled “Test Composer”# Create a test projectcomposer init --name=myapp --no-interaction
# Install a packagecomposer require monolog/monolog
# Verifyls vendor/ # Should see monolog and other dependenciesStep 2.7: PHP Extensions Overview (~5 min)
Section titled “Step 2.7: PHP Extensions Overview (~5 min)”Understand essential PHP extensions for development.
Core Extensions (Usually Pre-installed)
Section titled “Core Extensions (Usually Pre-installed)”These come with PHP but you should verify:
# Check installed extensionsphp -m
# Common extensions you'll need:| Extension | Purpose | Java Equivalent |
|---|---|---|
| json | JSON encoding/decoding | Jackson, Gson |
| mbstring | Multi-byte string handling | Built into Java |
| xml | XML processing | JAXB, DOM Parser |
| curl | HTTP client | HttpClient, OkHttp |
| pdo | Database abstraction | JDBC |
| zip | ZIP file handling | java.util.zip |
| openssl | Cryptography | java.security |
Installing Additional Extensions
Section titled “Installing Additional Extensions”::: code-group
# Database driverssudo apt install php8.4-mysql php8.4-pgsql php8.4-sqlite3
# Web developmentsudo apt install php8.4-curl php8.4-gd php8.4-xml
# Performancesudo apt install php8.4-opcache php8.4-apcu
# Verifyphp -m | grep -i mysql# Most extensions included with Homebrew PHP# For additional ones:pecl install apcupecl install redis# Edit php.ini and uncomment extensions:extension=curlextension=mbstringextension=pdo_mysql
# Restart web server after changes:::
Verification Script
Section titled “Verification Script”Create check-extensions.php:
<?php
$required = ['json', 'mbstring', 'xml', 'curl', 'pdo', 'openssl'];$missing = [];
foreach ($required as $ext) { if (!extension_loaded($ext)) { $missing[] = $ext; }}
if (empty($missing)) { echo "✅ All required extensions are installed!\n"; echo "\nInstalled extensions:\n"; foreach ($required as $ext) { echo " - $ext\n"; }} else { echo "❌ Missing extensions:\n"; foreach ($missing as $ext) { echo " - $ext\n"; } exit(1);}Run it:
php check-extensions.phpStep 2.8: PHP Configuration Basics (~5 min)
Section titled “Step 2.8: PHP Configuration Basics (~5 min)”Understand PHP’s configuration system and how it compares to Java’s configuration approach.
Finding Your php.ini File
Section titled “Finding Your php.ini File”Unlike Java’s application.properties or application.yml, PHP uses a single php.ini file for configuration. However, PHP can have multiple php.ini files (one for CLI, one for web server).
# Find which php.ini file PHP is usingphp --ini
# Output example:# Configuration File (php.ini) Path: /usr/local/etc/php/8.4# Loaded Configuration File: /usr/local/etc/php/8.4/php.ini# Scan for additional .ini files in: /usr/local/etc/php/8.4/conf.dKey Configuration Settings for Development
Section titled “Key Configuration Settings for Development”For Java developers, here’s how PHP configuration compares:
::: code-group
; Error reporting (similar to Java logging levels)error_reporting = E_ALLdisplay_errors = On ; Show errors in developmentdisplay_startup_errors = On ; Show startup errorslog_errors = On ; Log errors to fileerror_log = /var/log/php_errors.log
; Memory and execution limitsmemory_limit = 256M ; Like -Xmx in Javamax_execution_time = 30 ; Script timeout (seconds)
; File uploadsupload_max_filesize = 10Mpost_max_size = 20M
; Date and timezone (important!)date.timezone = America/New_York# Error handlinglogging.level.root=INFOlogging.level.com.example=DEBUG
# Server configurationserver.port=8080spring.servlet.multipart.max-file-size=10MBspring.servlet.multipart.max-request-size=20MB
# Memory (JVM arguments)# -Xmx256m:::
Setting Configuration Programmatically
Section titled “Setting Configuration Programmatically”Unlike Java where you typically configure via properties files or annotations, PHP allows runtime configuration:
<?php
// Set configuration at runtime (like System.setProperty in Java)ini_set('display_errors', '1');ini_set('error_reporting', E_ALL);ini_set('memory_limit', '512M');
// Get current configuration$memoryLimit = ini_get('memory_limit');echo "Memory limit: $memoryLimit\n";
// Check if a setting is changeableif (ini_get('display_errors') === false) { echo "display_errors cannot be changed\n";}Java Comparison:
// Java uses System properties or application configSystem.setProperty("log.level", "DEBUG");String logLevel = System.getProperty("log.level");Development vs Production Settings
Section titled “Development vs Production Settings”Development (php.ini):
display_errors = Ondisplay_startup_errors = Onerror_reporting = E_ALLlog_errors = OnProduction (php.ini):
display_errors = Off ; Never show errors to usersdisplay_startup_errors = Offerror_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICTlog_errors = On ; Always log, but don't display::: warning Security Note
Never set display_errors = On in production! This exposes sensitive information. Always log errors instead of displaying them.
:::
Why It Works
Section titled “Why It Works”PHP’s configuration system differs from Java:
| Aspect | Java | PHP |
|---|---|---|
| Configuration Files | Multiple (properties, YAML, XML) | Single php.ini (with includes) |
| Runtime Changes | Limited (System properties) | Extensive (ini_set()) |
| Per-Request Config | Application-level | Can change per script |
| Environment-Specific | Spring profiles, Maven profiles | Separate php.ini files or ini_set() |
| CLI vs Web | Same JVM settings | Different php.ini files possible |
Troubleshooting
Section titled “Troubleshooting”Problem: Changes to php.ini not taking effect
- Solution: Restart your web server (Apache/Nginx) or use
php --inito verify which file is loadedTerminal window # Find loaded configphp --ini# For web server, restart:sudo systemctl restart apache2 # or nginx
Problem: Need different settings for CLI vs web
- Solution: PHP can use different
php.inifiles. Check withphp --inifor CLI andphpinfo()for web server.
Step 3: Hello World Comparison (~10 min)
Section titled “Step 3: Hello World Comparison (~10 min)”Write and run your first PHP script, comparing it to Java.
Actions
Section titled “Actions”Step 1: Create your first PHP script
Create a file named hello.php:
::: code-group
<?php
// This is a comment in PHPecho "Hello, World!\n";
// More complex example$name = "Java Developer";echo "Welcome to PHP, $name!\n";public class Hello { // This is a comment in Java public static void main(String[] args) { System.out.println("Hello, World!");
// More complex example String name = "Java Developer"; System.out.println("Welcome to Java, " + name + "!"); }}:::
Step 2: Run the scripts
::: code-group
# Just run it directlyphp hello.php
# Output:# Hello, World!# Welcome to PHP, Java Developer!# Compile firstjavac Hello.java
# Then runjava Hello
# Output:# Hello, World!# Welcome to Java, Java Developer!:::
Expected Result
Section titled “Expected Result”You should see:
Hello, World!Welcome to PHP, Java Developer!Why It Works
Section titled “Why It Works”Let’s break down the key differences:
1. Entry Point
- Java: Requires
public static void main(String[] args)method in a class - PHP: Top-level code execution—no class or method required (though you can use them)
2. Syntax
- Java: Statements end with
;, variables are typed (String name) - PHP: Statements end with
;, variables start with$and are dynamically typed (or optionally typed)
3. Output
- Java:
System.out.println() - PHP:
echoorprint(simpler, built-in language constructs)
4. String Interpolation
- Java: Concatenation with
+orString.format() - PHP: Direct variable interpolation in double-quoted strings:
"$variable"
5. Execution
- Java: Compile, then run
- PHP: Run directly (interpretation + opcache)
::: tip No Boilerplate PHP’s lack of required boilerplate (no classes, no main method) makes it great for scripting and rapid development. You can add structure as needed for larger applications. :::
Step 3.5: PHP Tags and Syntax Basics (~5 min)
Section titled “Step 3.5: PHP Tags and Syntax Basics (~5 min)”Understand PHP’s tag syntax and how it differs from Java’s file structure.
PHP Opening and Closing Tags
Section titled “PHP Opening and Closing Tags”PHP code must be enclosed in special tags. Unlike Java where the entire file is code, PHP can mix with HTML:
<?php// Pure PHP file - all code hereecho "Hello, World!\n";<!DOCTYPE html><html><head> <title>PHP Example</title></head><body> <?php // PHP code embedded in HTML $name = "Java Developer"; echo "<h1>Welcome, $name!</h1>"; ?></body></html>Closing Tags: When to Omit
Section titled “Closing Tags: When to Omit”PSR-12 Standard (Recommended):
For pure PHP files (no HTML), omit the closing tag ?>:
<?php
declare(strict_types=1);
class Person{ // Class code}// No closing tag - this is correct!Why omit the closing tag?
- Prevents accidental whitespace/newlines after
?>from being sent to output - Avoids “headers already sent” errors
- Follows PSR-12 coding standard
When to include closing tag:
- Only when mixing PHP with HTML/other content
- In template files (
.phtmlfiles)
Short Echo Syntax
Section titled “Short Echo Syntax”PHP provides a shorthand for echo:
<?php$name = "Alice";?>
<!-- Long form --><?php echo $name; ?>
<!-- Short form (recommended in templates) --><?= $name ?>
<!-- Both output: Alice -->Java Comparison:
// Java doesn't have template syntax built-in// You'd use JSP, Thymeleaf, or similar:// <c:out value="${name}" />PHP Tags Comparison
Section titled “PHP Tags Comparison”| Tag Type | Syntax | Use Case |
|---|---|---|
| Standard | <?php ... ?> | Always works, recommended |
| Short Echo | <?= ... ?> | Templates only (must enable short_open_tag) |
| Short Tags | <? ... ?> | Deprecated, don’t use |
::: warning Short Tags
Avoid <? ... ?> (short tags). They’re deprecated and may not work on all servers. Always use <?php ... ?> or <?= ... ?> for echo.
:::
File Organization: No Classpath
Section titled “File Organization: No Classpath”Unlike Java where classes are automatically found via the classpath, PHP requires explicit file inclusion:
Java:
// Java automatically finds classes via classpathimport com.example.User;User user = new User(); // ClassLoader finds itPHP (without autoloading):
<?php
// Must explicitly include/require the filerequire_once 'Person.php'; // Like import, but loads the file
$person = new Person("Alice", 30);PHP (with autoloading - covered in Chapter 6):
<?php
// With Composer autoloader (like Java's classpath)require 'vendor/autoload.php';
use App\Models\Person; // Now works like Java import$person = new Person("Alice", 30);Why It Works
Section titled “Why It Works”PHP’s tag system allows:
- Pure PHP files: Just code, no HTML
- Mixed files: PHP embedded in HTML (like JSP)
- Templates: PHP generating HTML dynamically
This flexibility is different from Java where:
.javafiles are always pure Java code- Templates use separate technologies (JSP, Thymeleaf, etc.)
- No mixing of code and markup in source files
Troubleshooting
Section titled “Troubleshooting”Problem: “Parse error: syntax error, unexpected ’?’”
- Cause: Short tags
<?not enabled or using wrong syntax - Solution: Use
<?phpinstead of<?
Problem: “Headers already sent” error
- Cause: Whitespace or output before
<?phptag or after?>tag - Solution: Remove closing
?>tag in pure PHP files, check for whitespace before opening tag
Problem: Short echo <?= not working
- Cause:
short_open_tagdisabled in php.ini - Solution: Enable it or use
<?php echoinstead
Step 4: Creating a Simple Class (~10 min)
Section titled “Step 4: Creating a Simple Class (~10 min)”Compare object-oriented programming basics between Java and PHP.
Actions
Section titled “Actions”Create a Person class in both languages:
::: code-group
<?php
declare(strict_types=1); // Enable strict type checking (optional but recommended)
class Person{ private string $name; private int $age;
// Constructor public function __construct(string $name, int $age) { $this->name = $name; $this->age = $age; }
// Getter methods public function getName(): string { return $this->name; }
public function getAge(): int { return $this->age; }
// Method public function introduce(): string { return "Hi, I'm {$this->name} and I'm {$this->age} years old."; }}
// Usage (in the same file or another file)$person = new Person("Alice", 30);echo $person->introduce() . "\n";echo "Name: " . $person->getName() . "\n";public class Person { private String name; private int age;
// Constructor public Person(String name, int age) { this.name = name; this.age = age; }
// Getter methods public String getName() { return name; }
public int getAge() { return age; }
// Method public String introduce() { return String.format("Hi, I'm %s and I'm %d years old.", name, age); }
// Usage public static void main(String[] args) { Person person = new Person("Alice", 30); System.out.println(person.introduce()); System.out.println("Name: " + person.getName()); }}:::
Expected Result
Section titled “Expected Result”Hi, I'm Alice and I'm 30 years old.Name: AliceKey Differences Explained
Section titled “Key Differences Explained”| Feature | Java | PHP |
|---|---|---|
| Class Declaration | public class Person | class Person (public by default) |
| Properties | private String name; | private string $name; (note: lowercase string) |
| Constructor | public Person(...) | public function __construct(...) |
| Method Declaration | public String getName() | public function getName(): string (return type after :) |
| This Reference | this.name | $this->name (uses -> operator) |
| Type Hints | Required | Optional (but recommended with declare(strict_types=1)) |
| Instantiation | new Person(...) | new Person(...) (same!) |
::: warning Important Differences
- Property access: PHP uses
->instead of. - Variables: Always start with
$in PHP - Constructor name: PHP uses
__construct()instead of class name - Type declarations: PHP uses lowercase type names (
string,int,bool) - Strict types: PHP needs
declare(strict_types=1);for type safety similar to Java :::
Why It Works
Section titled “Why It Works”Modern PHP (7.4+) supports:
- Type hints for parameters and return types
- Property types (PHP 7.4+)
- Visibility modifiers (public, private, protected)
- Interfaces and abstract classes
- Traits (similar to Java’s interface default methods)
This makes PHP’s OOP model very similar to Java’s, with the main difference being syntax.
Step 5: Setting Up Your IDE (~10 min)
Section titled “Step 5: Setting Up Your IDE (~10 min)”Configure your IDE for productive PHP development.
Actions
Section titled “Actions”Choose your preferred IDE:
::: code-group
1. Download PhpStorm from jetbrains.com/phpstorm2. Install and launch3. Configure PHP Interpreter: - Go to Settings/Preferences → PHP - Click "..." next to CLI Interpreter - Click "+" and select your PHP installation - Verify version shows PHP 8.44. Enable PHP 8.4 language level: - Settings → PHP → PHP Language Level → 8.4
PhpStorm Features for Java Developers:✅ Familiar JetBrains interface✅ Excellent autocomplete and refactoring✅ Built-in debugger (like IntelliJ's debugger)✅ Integrated Composer support (like Maven/Gradle)✅ Database tools built-in1. Install VS Code from code.visualstudio.com2. Install PHP extensions: - PHP Intelephense (best PHP autocomplete) - PHP Debug - PHP Namespace Resolver - PHPDoc Comment
3. Configure PHP executable: - Open Settings (Cmd/Ctrl + ,) - Search for "php.validate.executablePath" - Set to your PHP installation path
4. Create .vscode/settings.json in your project:{ "php.validate.executablePath": "/usr/local/bin/php", "php.suggest.basic": false, "intelephense.diagnostics.undefinedTypes": true, "intelephense.diagnostics.undefinedFunctions": true}1. IntelliJ IDEA Ultimate includes PHP support2. Enable PHP plugin: - Settings → Plugins → Search "PHP" - Enable "PHP" plugin3. Configure PHP interpreter: - Settings → PHP → CLI Interpreter - Add your PHP 8.4 installation4. Set language level to PHP 8.4
Benefits for Java developers:✅ Same IDE for Java and PHP✅ Familiar interface and shortcuts✅ Unified project view✅ Database tools work the same:::
Expected Result
Section titled “Expected Result”After setup, you should have:
- Syntax highlighting for PHP code
- Autocomplete for PHP functions and classes
- Error detection for type mismatches and undefined variables
- Go to definition (Cmd/Ctrl + Click)
- Integrated terminal for running PHP commands
Testing Your IDE Setup
Section titled “Testing Your IDE Setup”Create a new PHP file and test autocomplete:
<?php
// Type this and test autocomplete:$text = "hello";$text-> // IDE should show string methods
// Test type checking:function add(int $a, int $b): int { return $a + $b;}
add("hello", "world"); // IDE should show error::: tip Keyboard Shortcuts Most shortcuts you know from Java development work in PHP:
- Cmd/Ctrl + Click: Go to definition
- Cmd/Ctrl + Space: Autocomplete
- Cmd/Ctrl + B: Go to declaration
- Alt + Enter: Quick fixes
- Shift + Shift: Search everywhere (PhpStorm/IntelliJ) :::
Step 6: Your First Web Response (~10 min)
Section titled “Step 6: Your First Web Response (~10 min)”Create a simple web endpoint in PHP and compare it to a Java servlet.
Actions
Section titled “Actions”Step 1: Create a simple PHP web response
Create index.php:
<?php
declare(strict_types=1);
// Set response headersheader('Content-Type: application/json');
// Get request method$method = $_SERVER['REQUEST_METHOD'];
// Simple routingif ($method === 'GET') { $response = [ 'message' => 'Hello from PHP!', 'timestamp' => time(), 'version' => phpversion() ];
echo json_encode($response, JSON_PRETTY_PRINT);} else { http_response_code(405); echo json_encode(['error' => 'Method not allowed']);}Step 2: Run PHP’s built-in web server
# Start the server (similar to Spring Boot's embedded server)php -S localhost:8000
# You should see:# PHP 8.4.x Development Server (http://localhost:8000) startedStep 3: Test the endpoint
# Test with curlcurl http://localhost:8000/index.php
# Or open in browser:# http://localhost:8000/index.phpFor comparison, here’s the Java servlet equivalent:
@WebServlet("/hello")public class HelloServlet extends HttpServlet {
@Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException { response.setContentType("application/json");
JSONObject json = new JSONObject(); json.put("message", "Hello from Java!"); json.put("timestamp", System.currentTimeMillis() / 1000); json.put("version", System.getProperty("java.version"));
response.getWriter().write(json.toString()); }}Expected Result
Section titled “Expected Result”{ "message": "Hello from PHP!", "timestamp": 1701234567, "version": "8.4.0"}Why It Works
Section titled “Why It Works”Key Differences:
-
No Application Server Required
- Java: Needs Tomcat, Jetty, or embedded server
- PHP: Built-in development server or Apache/Nginx
-
Request Handling
- Java: Servlet classes with lifecycle methods
- PHP: Script executes per request, accessing
$_SERVER,$_GET,$_POSTsuperglobals
-
Response Generation
- Java: Write to
responseobject - PHP:
echooutput directly, set headers withheader()
- Java: Write to
-
JSON Handling
- Java: Use library like Jackson or GSON
- PHP: Built-in
json_encode()andjson_decode()
::: warning Important PHP Concepts
- Superglobals:
$_GET,$_POST,$_SERVERare built-in arrays containing request data - Output buffering: Everything you
echogoes to the response - Headers: Must be set before any output with
header() - Request lifecycle: Each request runs the script from start to finish (stateless by default) :::
Step 7: Project Structure Comparison (~5 min)
Section titled “Step 7: Project Structure Comparison (~5 min)”Understand how PHP projects are structured compared to Java projects.
Typical Structure Comparison
Section titled “Typical Structure Comparison”::: code-group
my-php-project/├── composer.json # Dependencies (like pom.xml)├── composer.lock # Lock file (like pom.xml.lock)├── vendor/ # Dependencies (like .m2 or build/libs)├── public/ # Web root (accessible to browser)│ ├── index.php # Entry point│ └── assets/ # CSS, JS, images├── src/ # Application code│ ├── Controller/│ ├── Model/│ └── Service/├── config/ # Configuration files│ └── database.php├── tests/ # PHPUnit tests│ └── Unit/├── .env # Environment variables└── README.mdmy-java-project/├── pom.xml # Dependencies├── target/ # Build output├── src/│ ├── main/│ │ ├── java/ # Source code│ │ │ └── com/example/│ │ │ ├── controller/│ │ │ ├── model/│ │ │ └── service/│ │ └── resources/ # Config files│ │ └── application.properties│ └── test/ # JUnit tests│ └── java/│ └── com/example/├── .env # Environment variables└── README.md:::
Key Parallels:
| PHP | Java | Purpose |
|---|---|---|
composer.json | pom.xml / build.gradle | Dependency management |
vendor/ | target/ / .m2/ | Dependencies |
src/ | src/main/java/ | Source code |
tests/ | src/test/java/ | Tests |
public/index.php | @SpringBootApplication | Entry point |
config/ | src/main/resources/ | Configuration |
.env | .env / application.properties | Environment config |
Exercises
Section titled “Exercises”::: tip Practice Time Complete these exercises to reinforce your learning: :::
Exercise 1: Hello You!
Section titled “Exercise 1: Hello You!”Modify hello.php to accept a name as a command-line argument.
Expected behavior:
php hello.php Alice# Output: Hello, Alice!
php hello.php# Output: Hello, World!Hints:
- In Java:
args[0]for command-line arguments - In PHP:
$argv[1]for command-line arguments - Check if argument exists before using it
Solution
<?php
// Get name from command line, default to "World"$name = $argv[1] ?? "World";
echo "Hello, $name!\n";Comparison with Java:
public class Hello { public static void main(String[] args) { String name = args.length > 0 ? args[0] : "World"; System.out.println("Hello, " + name + "!"); }}Exercise 2: Calculator Class
Section titled “Exercise 2: Calculator Class”Create a Calculator class in PHP with methods for basic operations.
Requirements:
- Methods:
add(),subtract(),multiply(),divide() - All methods should use type hints
divide()should throw an exception for division by zero- Create a test script to verify all methods work
Expected usage:
$calc = new Calculator();echo $calc->add(5, 3); // 8echo $calc->divide(10, 2); // 5echo $calc->divide(10, 0); // Exception thrownSolution
<?php
declare(strict_types=1);
class Calculator{public function add(int|float $a, int|float $b): int|float{ return $a + $b;}
public function subtract(int|float $a, int|float $b): int|float{ return $a - $b;}
public function multiply(int|float $a, int|float $b): int|float{ return $a * $b;}
public function divide(int|float $a, int|float $b): float{ if ($b === 0) { throw new InvalidArgumentException("Division by zero"); } return $a / $b;}}
// Test script $calc = new Calculator();
try { echo “5 + 3 = ” . calc->subtract(10, 4) . “\n”; echo “6 * 7 = ” . calc->divide(15, 3) . “\n”;
// This will throw an exceptionecho $calc->divide(10, 0);} catch (InvalidArgumentException e) { echo "Error: " . e->getMessage() . “\n”; }
**Note:** PHP 8+ supports union types (`int|float`), similar to Java's type system.
</details>
### Exercise 3: JSON API
Create a simple REST API endpoint that returns information about a product.
**Requirements:**- Endpoint: `/product.php?id=123`- Return JSON with product details- Handle missing `id` parameter- Return proper HTTP status codes
<details><summary>Solution</summary>
```php# filename: product.php<?php
declare(strict_types=1);
header('Content-Type: application/json');
// Simulated database$products = [ 123 => ['id' => 123, 'name' => 'Laptop', 'price' => 999.99], 456 => ['id' => 456, 'name' => 'Mouse', 'price' => 29.99],];
// Get product ID from query parameter$id = isset($_GET['id']) ? (int)$_GET['id'] : null;
if ($id === null) { http_response_code(400); echo json_encode(['error' => 'Product ID is required']); exit;}
if (!isset($products[$id])) { http_response_code(404); echo json_encode(['error' => 'Product not found']); exit;}
// Return productecho json_encode($products[$id], JSON_PRETTY_PRINT);Test it:
php -S localhost:8000
# In another terminal:curl http://localhost:8000/product.php?id=123curl http://localhost:8000/product.php?id=999 # 404curl http://localhost:8000/product.php # 400Wrap-up Checklist
Section titled “Wrap-up Checklist”Before moving to the next chapter, make sure you can:
- Run
php --versionand see PHP 8.4 - Execute PHP scripts from the command line
- Create and instantiate PHP classes with type hints
- Understand the differences between Java and PHP syntax
- Start PHP’s built-in web server
- Return JSON responses from PHP scripts
- Configure your IDE for PHP development
- Explain PHP’s execution model vs Java’s
::: tip Ready for More? In Chapter 1: Types, Variables & Operators, we’ll dive deeper into PHP’s type system and see how it compares to Java’s strong typing. :::
Further Reading
Section titled “Further Reading”PHP Documentation:
For Java Developers:
- PHP: The Right Way
- Migrating from Java to PHP
- PSR Standards - PHP’s equivalent to Java conventions
Tools:
- PhpStorm - The JetBrains PHP IDE
- Composer - Dependency manager (we’ll cover this in Chapter 8)
- PHP The Right Way - Best practices guide