Skip to content

00: Setup & First Comparison

PHP Setup Hero

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.

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

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

If you’re already familiar with command-line tools and want to get up and running quickly:

Terminal window
# macOS (with Homebrew)
brew install php@8.4
# Verify installation
php --version
# Create your first PHP script
echo '<?php echo "Hello, PHP!";' > hello.php
# Run it
php hello.php

For detailed setup instructions and comparisons with Java, continue reading below.

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’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)
AspectJavaPHP
CompilationCompiled to bytecodeInterpreted (with opcache)
ExecutionRuns in JVMNative execution via PHP runtime
DeploymentJAR/WAR filesSource files directly
StartupApplication server (long-running)Request-based (typically)
ReloadRestart requiredChanges reflected immediately
PerformanceJIT compilation, warm-upOpcache + 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. :::

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)

Install PHP 8.4 on your development machine.

::: code-group

Terminal window
# 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.4
brew install php@8.4
# Verify installation
php --version
# Should output: PHP 8.4.x (cli)...
Terminal window
# Update package lists
sudo apt update
# Add PHP repository
sudo apt install software-properties-common
sudo add-apt-repository ppa:ondrej/php
# Install PHP 8.4
sudo apt install php8.4 php8.4-cli php8.4-common php8.4-mbstring php8.4-xml php8.4-curl
# Verify installation
php --version
Terminal window
# Option 1: Using Chocolatey
choco 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 installation
php --version
Terminal window
# Enable REMI repository
sudo dnf install https://rpms.remirepo.net/fedora/remi-release-XX.rpm
# Install PHP 8.4
sudo dnf module reset php
sudo dnf module install php:remi-8.4
# Verify installation
php --version

:::

Running php --version should display:

PHP 8.4.x (cli) (built: ...)
Copyright (c) The PHP Group
Zend 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. :::

PHP’s installation includes:

  • PHP CLI: Command-line interpreter (like java command)
  • 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)

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 location
    which php # macOS/Linux
    where 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 Homebrew
    brew unlink php@8.3 && brew link php@8.4

Problem: Missing extensions

  • Solution: Install required extensions:
    Terminal window
    # Ubuntu/Debian
    sudo apt install php8.4-<extension-name>
    # macOS
    pecl 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.

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
Terminal window
# Pull official PHP image
docker pull php:8.4-cli
# Run PHP in Docker
docker run --rm php:8.4-cli php --version
# Run a PHP script
docker run --rm -v $(pwd):/app php:8.4-cli php /app/hello.php
# Interactive PHP shell
docker run --rm -it php:8.4-cli php -a

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.d

Run with:

Terminal window
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 :::

Install Composer, PHP’s dependency manager (like Maven/Gradle).

::: code-group

Terminal window
# Download and install globally
php -r "copy('https://getcomposer.org/installer', 'composer-setup.php');"
php composer-setup.php
php -r "unlink('composer-setup.php');"
sudo mv composer.phar /usr/local/bin/composer
# Verify installation
composer --version
Terminal window
# Download and run Composer-Setup.exe from:
# https://getcomposer.org/Composer-Setup.exe
# After installation, verify:
composer --version
Terminal window
# Use Composer Docker image
docker 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'

:::

Java ToolPHP EquivalentPurpose
MavenComposerDependency management
pom.xmlcomposer.jsonProject configuration
mvn installcomposer installInstall dependencies
.m2/repositoryvendor/Dependencies location
Terminal window
# Create a test project
composer init --name=myapp --no-interaction
# Install a package
composer require monolog/monolog
# Verify
ls vendor/ # Should see monolog and other dependencies

Step 2.7: PHP Extensions Overview (~5 min)

Section titled “Step 2.7: PHP Extensions Overview (~5 min)”

Understand essential PHP extensions for development.

These come with PHP but you should verify:

Terminal window
# Check installed extensions
php -m
# Common extensions you'll need:
ExtensionPurposeJava Equivalent
jsonJSON encoding/decodingJackson, Gson
mbstringMulti-byte string handlingBuilt into Java
xmlXML processingJAXB, DOM Parser
curlHTTP clientHttpClient, OkHttp
pdoDatabase abstractionJDBC
zipZIP file handlingjava.util.zip
opensslCryptographyjava.security

::: code-group

Terminal window
# Database drivers
sudo apt install php8.4-mysql php8.4-pgsql php8.4-sqlite3
# Web development
sudo apt install php8.4-curl php8.4-gd php8.4-xml
# Performance
sudo apt install php8.4-opcache php8.4-apcu
# Verify
php -m | grep -i mysql
Terminal window
# Most extensions included with Homebrew PHP
# For additional ones:
pecl install apcu
pecl install redis
Terminal window
# Edit php.ini and uncomment extensions:
extension=curl
extension=mbstring
extension=pdo_mysql
# Restart web server after changes

:::

Create check-extensions.php:

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:

Terminal window
php check-extensions.php

Step 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.

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).

Terminal window
# Find which php.ini file PHP is using
php --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.d

Key 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_ALL
display_errors = On ; Show errors in development
display_startup_errors = On ; Show startup errors
log_errors = On ; Log errors to file
error_log = /var/log/php_errors.log
; Memory and execution limits
memory_limit = 256M ; Like -Xmx in Java
max_execution_time = 30 ; Script timeout (seconds)
; File uploads
upload_max_filesize = 10M
post_max_size = 20M
; Date and timezone (important!)
date.timezone = America/New_York
# Error handling
logging.level.root=INFO
logging.level.com.example=DEBUG
# Server configuration
server.port=8080
spring.servlet.multipart.max-file-size=10MB
spring.servlet.multipart.max-request-size=20MB
# Memory (JVM arguments)
# -Xmx256m

:::

Unlike Java where you typically configure via properties files or annotations, PHP allows runtime configuration:

config-example.php
<?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 changeable
if (ini_get('display_errors') === false) {
echo "display_errors cannot be changed\n";
}

Java Comparison:

// Java uses System properties or application config
System.setProperty("log.level", "DEBUG");
String logLevel = System.getProperty("log.level");

Development (php.ini):

display_errors = On
display_startup_errors = On
error_reporting = E_ALL
log_errors = On

Production (php.ini):

display_errors = Off ; Never show errors to users
display_startup_errors = Off
error_reporting = E_ALL & ~E_DEPRECATED & ~E_STRICT
log_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. :::

PHP’s configuration system differs from Java:

AspectJavaPHP
Configuration FilesMultiple (properties, YAML, XML)Single php.ini (with includes)
Runtime ChangesLimited (System properties)Extensive (ini_set())
Per-Request ConfigApplication-levelCan change per script
Environment-SpecificSpring profiles, Maven profilesSeparate php.ini files or ini_set()
CLI vs WebSame JVM settingsDifferent php.ini files possible

Problem: Changes to php.ini not taking effect

  • Solution: Restart your web server (Apache/Nginx) or use php --ini to verify which file is loaded
    Terminal window
    # Find loaded config
    php --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.ini files. Check with php --ini for CLI and phpinfo() for web server.

Write and run your first PHP script, comparing it to Java.

Step 1: Create your first PHP script

Create a file named hello.php:

::: code-group

hello.php
<?php
// This is a comment in PHP
echo "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

Terminal window
# Just run it directly
php hello.php
# Output:
# Hello, World!
# Welcome to PHP, Java Developer!
Terminal window
# Compile first
javac Hello.java
# Then run
java Hello
# Output:
# Hello, World!
# Welcome to Java, Java Developer!

:::

You should see:

Hello, World!
Welcome to PHP, Java Developer!

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: echo or print (simpler, built-in language constructs)

4. String Interpolation

  • Java: Concatenation with + or String.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 code must be enclosed in special tags. Unlike Java where the entire file is code, PHP can mix with HTML:

tags-example.php
<?php
// Pure PHP file - all code here
echo "Hello, World!\n";
mixed-html.php
<!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>

PSR-12 Standard (Recommended):

For pure PHP files (no HTML), omit the closing tag ?>:

person.php
<?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 (.phtml files)

PHP provides a shorthand for echo:

short-echo.php
<?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}" />
Tag TypeSyntaxUse 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. :::

Unlike Java where classes are automatically found via the classpath, PHP requires explicit file inclusion:

Java:

// Java automatically finds classes via classpath
import com.example.User;
User user = new User(); // ClassLoader finds it

PHP (without autoloading):

main.php
<?php
// Must explicitly include/require the file
require_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);

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:

  • .java files are always pure Java code
  • Templates use separate technologies (JSP, Thymeleaf, etc.)
  • No mixing of code and markup in source files

Problem: “Parse error: syntax error, unexpected ’?’”

  • Cause: Short tags <? not enabled or using wrong syntax
  • Solution: Use <?php instead of <?

Problem: “Headers already sent” error

  • Cause: Whitespace or output before <?php tag 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_tag disabled in php.ini
  • Solution: Enable it or use <?php echo instead

Compare object-oriented programming basics between Java and PHP.

Create a Person class in both languages:

::: code-group

Person.php
<?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());
}
}

:::

Hi, I'm Alice and I'm 30 years old.
Name: Alice
FeatureJavaPHP
Class Declarationpublic class Personclass Person (public by default)
Propertiesprivate String name;private string $name; (note: lowercase string)
Constructorpublic Person(...)public function __construct(...)
Method Declarationpublic String getName()public function getName(): string (return type after :)
This Referencethis.name$this->name (uses -> operator)
Type HintsRequiredOptional (but recommended with declare(strict_types=1))
Instantiationnew Person(...)new Person(...) (same!)

::: warning Important Differences

  1. Property access: PHP uses -> instead of .
  2. Variables: Always start with $ in PHP
  3. Constructor name: PHP uses __construct() instead of class name
  4. Type declarations: PHP uses lowercase type names (string, int, bool)
  5. Strict types: PHP needs declare(strict_types=1); for type safety similar to Java :::

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.


Configure your IDE for productive PHP development.

Choose your preferred IDE:

::: code-group

1. Download PhpStorm from jetbrains.com/phpstorm
2. Install and launch
3. Configure PHP Interpreter:
- Go to Settings/Preferences → PHP
- Click "..." next to CLI Interpreter
- Click "+" and select your PHP installation
- Verify version shows PHP 8.4
4. 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-in
1. Install VS Code from code.visualstudio.com
2. 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 support
2. Enable PHP plugin:
- Settings → Plugins → Search "PHP"
- Enable "PHP" plugin
3. Configure PHP interpreter:
- Settings → PHP → CLI Interpreter
- Add your PHP 8.4 installation
4. 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

:::

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

Create a new PHP file and test autocomplete:

test-ide.php
<?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) :::

Create a simple web endpoint in PHP and compare it to a Java servlet.

Step 1: Create a simple PHP web response

Create index.php:

index.php
<?php
declare(strict_types=1);
// Set response headers
header('Content-Type: application/json');
// Get request method
$method = $_SERVER['REQUEST_METHOD'];
// Simple routing
if ($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

Terminal window
# 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) started

Step 3: Test the endpoint

Terminal window
# Test with curl
curl http://localhost:8000/index.php
# Or open in browser:
# http://localhost:8000/index.php

For 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());
}
}
{
"message": "Hello from PHP!",
"timestamp": 1701234567,
"version": "8.4.0"
}

Key Differences:

  1. No Application Server Required

    • Java: Needs Tomcat, Jetty, or embedded server
    • PHP: Built-in development server or Apache/Nginx
  2. Request Handling

    • Java: Servlet classes with lifecycle methods
    • PHP: Script executes per request, accessing $_SERVER, $_GET, $_POST superglobals
  3. Response Generation

    • Java: Write to response object
    • PHP: echo output directly, set headers with header()
  4. JSON Handling

    • Java: Use library like Jackson or GSON
    • PHP: Built-in json_encode() and json_decode()

::: warning Important PHP Concepts

  • Superglobals: $_GET, $_POST, $_SERVER are built-in arrays containing request data
  • Output buffering: Everything you echo goes 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.

::: 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.md
my-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:

PHPJavaPurpose
composer.jsonpom.xml / build.gradleDependency management
vendor/target/ / .m2/Dependencies
src/src/main/java/Source code
tests/src/test/java/Tests
public/index.php@SpringBootApplicationEntry point
config/src/main/resources/Configuration
.env.env / application.propertiesEnvironment config

::: tip Practice Time Complete these exercises to reinforce your learning: :::

Modify hello.php to accept a name as a command-line argument.

Expected behavior:

Terminal window
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
hello.php
<?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 + "!");
}
}

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); // 8
echo $calc->divide(10, 2); // 5
echo $calc->divide(10, 0); // Exception thrown
Solution
Calculator.php
<?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>add(5,3)."\n";echo"104=".calc->add(5, 3) . "\n"; echo "10 - 4 = " . calc->subtract(10, 4) . “\n”; echo “6 * 7 = ” . calc>multiply(6,7)."\n";echo"15/3=".calc->multiply(6, 7) . "\n"; echo "15 / 3 = " . calc->divide(15, 3) . “\n”;

// This will throw an exception
echo $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 product
echo json_encode($products[$id], JSON_PRETTY_PRINT);

Test it:

Terminal window
php -S localhost:8000
# In another terminal:
curl http://localhost:8000/product.php?id=123
curl http://localhost:8000/product.php?id=999 # 404
curl http://localhost:8000/product.php # 400

Before moving to the next chapter, make sure you can:

  • Run php --version and 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. :::


PHP Documentation:

For Java Developers:

Tools: