PHPプログラマのためのPythonガイド
PHPのバックグラウンドを持ちながらPythonに挑戦するエンジニアのために、両言語の構文や機能を比較解説します。この記事では、PHP 8.xとPython 3.xの基本的な構文の違いから、よく使われる機能の対応表まで、実践的なコード例とともに紹介します。
目次
基本構文
スクリプト構造
PHP:
<?php
// PHPコードは <?php タグで始まります
echo "Hello, World!";
// 終了タグは省略可能(むしろ推奨)
Python:
# Pythonはタグが不要
print("Hello, World!")
# インデントがスコープを表します
変数定義
PHP:
<?php
$name = "John"; // 変数は$ で始まる
$age = 30; // 型宣言は不要
$isActive = true;
// PHP 7.4以降では型ヒントが使える
string $profession = "Developer";
Python:
name = "John" # 変数に$ は不要
age = 30 # 型宣言は不要
is_active = True # 真偽値は大文字始まり
# 型ヒントを使う場合(Python 3.5以降)
profession: str = "Developer"
コメント
PHP:
<?php
// 一行コメント
# これも一行コメント(あまり使われない)
/*
複数行
コメント
*/
/**
* ドキュメントコメント(PHPDoc形式)
* @param string $name 名前
* @return void
*/
Python:
# 一行コメント
"""
複数行
コメント(ドキュメンテーション文字列としても使用される)
"""
'''
これも複数行コメント
'''
def function(name: str) -> None:
"""
ドキュメンテーション文字列(ドックストリング)
Args:
name: 名前
Returns:
None
"""
pass
出力
PHP:
<?php
$name = "Alice";
// 複数の方法がある
echo "Hello, $name!"; // 変数展開あり
Python:
name = "Alice"
# こちらも複数の方法がある
print(f"Hello, {name}!") # f文字列(Python 3.6以降)
PHP:
echo 'Hello, ' . $name . '!'; // 結合演算子
Python:
print("Hello, " + name + "!") # 結合演算子
PHP:
print("Hello, $name!"); // 関数形式
Python:
print("Hello, {}!".format(name)) # format関数
PHP:
printf("Hello, %s!", $name); // フォーマット指定
Python:
print("Hello, %s!" % name) # C言語形式(非推奨)
PHP:
var_dump($name); // デバッグ情報
Python:
print(name) # 単純な出力
制御構文
条件分岐
PHP:
<?php
$score = 85;
// if-elseif-else
if ($score >= 90) {
echo "A";
} elseif ($score >= 80) {
echo "B";
} elseif ($score >= 70) {
echo "C";
} else {
echo "D";
}
Python:
score = 85
# if-elif-else
if score >= 90:
print("A")
elif score >= 80:
print("B")
elif score >= 70:
print("C")
else:
print("D")
PHP:
// 三項演算子
$result = ($score >= 60) ? "合格" : "不合格";
Python:
# 三項演算子に相当する式
result = "合格" if score >= 60 else "不合格"
PHP:
// switch文
switch ($score) {
case 100:
echo "満点";
break;
case 0:
echo "零点";
break;
default:
echo "その他";
break;
}
Python:
# Pythonにはswitch文がないが、Python 3.10からマッチング文が導入
# Python 3.10以降
match score:
case 100:
print("満点")
case 0:
print("零点")
case _:
print("その他")
PHP:
// PHP 8のマッチ式
$grade = match (true) {
$score >= 90 => "A",
$score >= 80 => "B",
$score >= 70 => "C",
default => "D",
};
Python:
# 従来のPythonではdictを使ったディスパッチも一般的
grade_map = {
range(90, 101): "A",
range(80, 90): "B",
range(70, 80): "C",
range(0, 70): "D"
}
grade = next((v for k, v in grade_map.items() if score in k), "Invalid")
ループ
PHP:
<?php
// for
for ($i = 0; $i < 5; $i++) {
echo $i;
}
Python:
# for(Pythonのforは常に反復可能オブジェクトを使う)
for i in range(5):
print(i)
PHP:
// while
$j = 0;
while ($j < 5) {
echo $j;
$j++;
}
Python:
# while
j = 0
while j < 5:
print(j)
j += 1
PHP:
// do-while
$k = 0;
do {
echo $k;
$k++;
} while ($k < 5);
Python:
# Pythonにはdo-whileがないので模倣する
k = 0
while True:
print(k)
k += 1
if k >= 5:
break
PHP:
// foreach(配列)
$colors = ["red", "green", "blue"];
foreach ($colors as $color) {
echo $color;
}
Python:
# リストのループ
colors = ["red", "green", "blue"]
for color in colors:
print(color)
PHP:
// foreach(連想配列)
$person = ["name" => "John", "age" => 30];
foreach ($person as $key => $value) {
echo "$key: $value";
}
Python:
# 辞書のループ
person = {"name": "John", "age": 30}
for key, value in person.items():
print(f"{key}: {value}")
PHP:
// インデックス付きループ(少し冗長)
$colors = ["red", "green", "blue"];
for ($i = 0; $i < count($colors); $i++) {
echo "$i: {$colors[$i]}";
}
Python:
# enumerate関数でインデックス付きループ
for index, color in enumerate(colors):
print(f"{index}: {color}")
ループ制御
PHP:
<?php
for ($i = 0; $i < 10; $i++) {
if ($i == 5) {
break; // ループを抜ける
}
if ($i % 2 == 0) {
continue; // 次の反復へ
}
echo $i; // 1, 3, 7, 9が出力される
}
Python:
for i in range(10):
if i == 5:
break # ループを抜ける
if i % 2 == 0:
continue # 次の反復へ
print(i) # 1, 3, 7, 9が出力される
オブジェクト指向プログラミング
クラス定義と継承
PHP:
<?php
// クラス定義
class Person {
// プロパティ(PHP 7.4以降で型宣言可能)
private string $name;
protected int $age;
public bool $isActive = true;
// コンストラクタ
public function __construct(string $name, int $age = 0) {
$this->name = $name;
$this->age = $age;
}
// メソッド
public function greet(): string {
return "Hello, I'm {$this->name}";
}
// ゲッター
public function getName(): string {
return $this->name;
}
// セッター
public function setName(string $name): void {
$this->name = $name;
}
}
Python:
# クラス定義
class Person:
# クラス変数
species = "Human"
# コンストラクタ
def __init__(self, name: str, age: int = 0):
# インスタンス変数
self.name = name # publicに相当
self._age = age # protectedの慣習(実際は普通にアクセス可能)
self.__active = True # privateに相当(名前修飾により隠蔽)
# メソッド
def greet(self) -> str:
return f"Hello, I'm {self.name}"
# プロパティゲッター
@property
def age(self) -> int:
return self._age
# プロパティセッター
@age.setter
def age(self, value: int) -> None:
if value >= 0:
self._age = value
PHP:
// 継承
class Employee extends Person {
private string $position;
public function __construct(string $name, int $age, string $position) {
parent::__construct($name, $age);
$this->position = $position;
}
// オーバーライド
public function greet(): string {
return parent::greet() . " and I work as a {$this->position}";
}
}
Python:
# 継承
class Employee(Person):
def __init__(self, name: str, age: int, position: str):
super().__init__(name, age) # 親クラスのコンストラクタを呼び出し
self.position = position
# オーバーライド
def greet(self) -> str:
return super().greet() + f" and I work as a {self.position}"
PHP:
// 使用例
$person = new Person("John", 30);
echo $person->greet(); // "Hello, I'm John"
$employee = new Employee("Alice", 25, "Developer");
echo $employee->greet(); // "Hello, I'm Alice and I work as a Developer"
Python:
# 使用例
person = Person("John", 30)
print(person.greet()) # "Hello, I'm John"
employee = Employee("Alice", 25, "Developer")
print(employee.greet()) # "Hello, I'm Alice and I work as a Developer"
抽象クラスとインターフェース
PHP:
<?php
// 抽象クラス
abstract class Vehicle {
protected string $brand;
public function __construct(string $brand) {
$this->brand = $brand;
}
// 抽象メソッド
abstract public function move(): string;
// 具象メソッド
public function getBrand(): string {
return $this->brand;
}
}
Python:
from abc import ABC, abstractmethod
# 抽象基底クラス
class Vehicle(ABC):
def __init__(self, brand: str):
self._brand = brand
# 抽象メソッド
@abstractmethod
def move(self) -> str:
pass
# 具象メソッド
def get_brand(self) -> str:
return self._brand
PHP:
// インターフェース
interface Chargeable {
public function charge(): void;
public function getBatteryLevel(): int;
}
Python:
# Pythonはマルチ継承を使ってインターフェースを模倣
class Chargeable(ABC):
@abstractmethod
def charge(self) -> None:
pass
@abstractmethod
def get_battery_level(self) -> int:
pass
PHP:
// 抽象クラスとインターフェースを実装
class ElectricCar extends Vehicle implements Chargeable {
private int $batteryLevel = 0;
public function move(): string {
return "Electric car {$this->brand} is moving silently";
}
public function charge(): void {
$this->batteryLevel = 100;
}
public function getBatteryLevel(): int {
return $this->batteryLevel;
}
}
Python:
# 抽象クラスとインターフェース相当を実装
class ElectricCar(Vehicle, Chargeable):
def __init__(self, brand: str):
super().__init__(brand)
self._battery_level = 0
def move(self) -> str:
return f"Electric car {self._brand} is moving silently"
def charge(self) -> None:
self._battery_level = 100
def get_battery_level(self) -> int:
return self._battery_level
PHP:
// 使用例
$tesla = new ElectricCar("Tesla");
echo $tesla->move();
$tesla->charge();
echo $tesla->getBatteryLevel(); // 100
Python:
# 使用例
tesla = ElectricCar("Tesla")
print(tesla.move())
tesla.charge()
print(tesla.get_battery_level()) # 100
トレイト/ミックスイン
PHP:
<?php
// トレイト
trait Loggable {
private array $logs = [];
public function log(string $message): void {
$this->logs[] = date('Y-m-d H:i:s') . ": $message";
}
public function getLogs(): array {
return $this->logs;
}
}
Python:
from datetime import datetime
# ミックスイン(Pythonではマルチ継承で実現)
class LoggableMixin:
def __init__(self):
self._logs = []
def log(self, message: str) -> None:
timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
self._logs.append(f"{timestamp}: {message}")
def get_logs(self) -> list:
return self._logs
PHP:
trait Serializable {
public function toJson(): string {
return json_encode(get_object_vars($this));
}
}
Python:
import json
class SerializableMixin:
def to_json(self) -> str:
return json.dumps(self.__dict__)
PHP:
// トレイトを使用するクラス
class User {
use Loggable, Serializable;
private string $name;
private string $email;
public function __construct(string $name, string $email) {
$this->name = $name;
$this->email = $email;
$this->log("User created");
}
}
Python:
# ミックスインを使用するクラス
class User(LoggableMixin, SerializableMixin):
def __init__(self, name: str, email: str):
LoggableMixin.__init__(self) # 明示的に初期化
self._name = name
self._email = email
self.log("User created")
PHP:
// 使用例
$user = new User("John", "john@example.com");
$user->log("Profile updated");
print_r($user->getLogs());
echo $user->toJson();
Python:
# 使用例
user = User("John", "john@example.com")
user.log("Profile updated")
print(user.get_logs())
print(user.to_json())
名前空間
PHP:
<?php
// ファイル: App/Models/User.php
namespace App\Models;
class User {
private string $name;
public function __construct(string $name) {
$this->name = $name;
}
}
Python:
# ファイル: app/models/user.py
class User:
def __init__(self, name: str):
self.name = name
PHP:
// ファイル: App/Controllers/UserController.php
namespace App\Controllers;
use App\Models\User;
use App\Services\Logger as LogService;
class UserController {
public function createUser(string $name): User {
$logger = new LogService();
$logger->log("Creating user: $name");
return new User($name);
}
}
Python:
# ファイル: app/controllers/user_controller.py
from app.models.user import User
from app.services.logger import Logger as LogService
class UserController:
def create_user(self, name: str) -> User:
logger = LogService()
logger.log(f"Creating user: {name}")
return User(name)
注意: Pythonのパッケージシステムでは、各ディレクトリに
__init__.py
ファイルを作成する必要があります。
例外処理
基本的な例外処理
PHP:
<?php
function divide($a, $b) {
if ($b === 0) {
throw new InvalidArgumentException("Division by zero");
}
return $a / $b;
}
Python:
def divide(a, b):
if b == 0:
raise ValueError("Division by zero")
return a / b
PHP:
// 例外をキャッチする
try {
echo divide(10, 2); // 5
echo divide(10, 0); // 例外発生
} catch (InvalidArgumentException $e) {
echo "エラー: " . $e->getMessage(); // "エラー: Division by zero"
} catch (Exception $e) {
echo "その他のエラー: " . $e->getMessage();
} finally {
echo "処理完了"; // 常に実行される
}
Python:
# 例外をキャッチする
try:
print(divide(10, 2)) # 5.0
print(divide(10, 0)) # 例外発生
except ValueError as e:
print(f"エラー: {e}") # "エラー: Division by zero"
except Exception as e:
print(f"その他のエラー: {e}")
finally:
print("処理完了") # 常に実行される
カスタム例外
PHP:
<?php
// カスタム例外クラス
class FileNotFoundException extends Exception {
public function __construct(string $path, int $code = 0, Exception $previous = null) {
$message = "File not found: $path";
parent::__construct($message, $code, $previous);
}
}
Python:
# カスタム例外クラス
class FileNotFoundException(Exception):
def __init__(self, path, *args, **kwargs):
self.path = path
message = f"File not found: {path}"
super().__init__(message, *args, **kwargs)
PHP:
function readFile(string $path) {
if (!file_exists($path)) {
throw new FileNotFoundException($path);
}
return file_get_contents($path);
}
Python:
def read_file(path):
import os
if not os.path.exists(path):
raise FileNotFoundException(path)
with open(path, 'r') as f:
return f.read()
PHP:
try {
$content = readFile("non_existent_file.txt");
} catch (FileNotFoundException $e) {
echo $e->getMessage();
} catch (Exception $e) {
echo "Unexpected error: " . $e->getMessage();
}
Python:
try:
content = read_file("non_existent_file.txt")
except FileNotFoundException as e:
print(e)
except Exception as e:
print(f"Unexpected error: {e}")
文字列処理
基本的な文字列操作
PHP:
<?php
// 文字列の連結
$first = "Hello";
$last = "World";
$message = $first . ", " . $last . "!"; // "Hello, World!"
Python:
# 文字列の連結
first = "Hello"
last = "World"
message = first + ", " + last + "!" # "Hello, World!"
# f文字列を使った連結(Python 3.6以降)
message = f"{first}, {last}!" # "Hello, World!"
PHP:
// 変数の展開
$name = "Alice";
$greeting = "Hello, $name!"; // "Hello, Alice!"
$greeting2 = 'Hello, ' . $name . '!'; // "Hello, Alice!"
Python:
# 変数の展開
name = "Alice"
greeting = f"Hello, {name}!" # "Hello, Alice!" (Python 3.6+)
greeting2 = "Hello, {}!".format(name) # "Hello, Alice!"
PHP:
// 文字列の長さ
$str = "こんにちは";
$length = strlen($str); // バイト長(マルチバイト文字に非対応)
$length_mb = mb_strlen($str); // 文字数(マルチバイト対応)
Python:
# 文字列の長さ(Pythonは常にUnicodeで文字数をカウント)
str_value = "こんにちは"
length = len(str_value) # 5
PHP:
// 部分文字列
$substr = substr("Hello, World!", 0, 5); // "Hello"
$substr_mb = mb_substr("こんにちは", 0, 2); // "こん"
Python:
# 部分文字列(スライス)
substr = "Hello, World!"[0:5] # "Hello"
substr2 = "こんにちは"[0:2] # "こん"
PHP:
// 文字列の検索
$pos = strpos("Hello, World!", "World"); // 7
$pos_mb = mb_strpos("こんにちは世界", "世界"); // 5
Python:
# 文字列の検索
pos = "Hello, World!".find("World") # 7
pos2 = "こんにちは世界".find("世界") # 5
PHP:
// 文字列の置換
$replaced = str_replace("World", "PHP", "Hello, World!"); // "Hello, PHP!"
Python:
# 文字列の置換
replaced = "Hello, World!".replace("World", "Python") # "Hello, Python!"
PHP:
// 大文字・小文字変換
$upper = strtoupper("hello"); // "HELLO"
$lower = strtolower("HELLO"); // "hello"
Python:
# 大文字・小文字変換
upper = "hello".upper() # "HELLO"
lower = "HELLO".lower() # "hello"
文字列分割と結合
PHP:
<?php
// 文字列を配列に分割
$parts = explode(",", "apple,banana,orange");
// ["apple", "banana", "orange"]
Python:
# 文字列を配列に分割
parts = "apple,banana,orange".split(",")
# ["apple", "banana", "orange"]
PHP:
// 配列を文字列に結合
$fruits = ["apple", "banana", "orange"];
$csv = implode(",", $fruits); // "apple,banana,orange"
Python:
# 配列を文字列に結合
fruits = ["apple", "banana", "orange"]
csv = ",".join(fruits) # "apple,banana,orange"
PHP:
// 正規表現による分割
$words = preg_split("/\s+/", "Hello World Test");
// ["Hello", "World", "Test"]
Python:
# 正規表現による分割
import re
words = re.split(r"\s+", "Hello World Test")
# ["Hello", "World", "Test"]
文字列のフォーマット
PHP:
<?php
$name = "John";
$age = 30;
// sprintf/printf
$formatted = sprintf("Name: %s, Age: %d", $name, $age);
printf("Name: %s, Age: %d", $name, $age); // 出力する
Python:
name = "John"
age = 30
# format関数
formatted = "Name: {}, Age: {}".format(name, age)
# f文字列(Python 3.6以降)
formatted = f"Name: {name}, Age: {age}"
PHP:
// 文字列補間
$formatted = "Name: $name, Age: $age";
Python:
# %演算子(古い方法)
formatted = "Name: %s, Age: %d" % (name, age)
PHP:
// number_format
$price = number_format(1234.56, 2); // "1,234.56"
Python:
# 数値のフォーマット
price = "{:,.2f}".format(1234.56) # "1,234.56"
# f文字列での数値フォーマット
price = f"{1234.56:,.2f}" # "1,234.56"
PHP:
// パディング
$padded = str_pad("Hello", 10, "-", STR_PAD_RIGHT); // "Hello-----"
Python:
# パディング
padded = "Hello".ljust(10, "-") # "Hello-----"
padded2 = f"{'Hello':<10}" # "Hello "(スペースで埋める)
配列と連想配列
配列の基本操作
PHP:
<?php
// 配列の作成
$fruits = ["apple", "banana", "orange"];
$numbers = array(1, 2, 3, 4, 5);
Python:
# リストの作成
fruits = ["apple", "banana", "orange"]
numbers = [1, 2, 3, 4, 5]
PHP:
// 要素へのアクセス
echo $fruits[0]; // "apple"
$fruits[1] = "grape"; // 更新
Python:
# 要素へのアクセス
print(fruits[0]) # "apple"
fruits[1] = "grape" # 更新
PHP:
// 配列の末尾に追加
$fruits[] = "kiwi"; // ["apple", "grape", "orange", "kiwi"]
array_push($fruits, "melon"); // ["apple", "grape", "orange", "kiwi", "melon"]
Python:
# リストの末尾に追加
fruits.append("kiwi") # ["apple", "grape", "orange", "kiwi"]
PHP:
// 配列の先頭に追加
array_unshift($fruits, "pear"); // ["pear", "apple", "grape", "orange", "kiwi", "melon"]
Python:
# リストの先頭に追加
fruits.insert(0, "pear") # ["pear", "apple", "grape", "orange", "kiwi"]
PHP:
// 配列の末尾から削除
$last = array_pop($fruits); // "melon"
Python:
# リストの末尾から削除
last = fruits.pop() # "kiwi"
PHP:
// 配列の先頭から削除
$first = array_shift($fruits); // "pear"
Python:
# リストの先頭から削除
first = fruits.pop(0) # "pear"
PHP:
// 配列の結合
$more_fruits = ["cherry", "peach"];
$all_fruits = array_merge($fruits, $more_fruits);
Python:
# リストの結合
more_fruits = ["cherry", "peach"]
all_fruits = fruits + more_fruits
# または
fruits.extend(more_fruits)
PHP:
// 配列のサイズ
$count = count($fruits);
Python:
# リストのサイズ
count = len(fruits)
PHP:
// 配列のソート
sort($fruits); // アルファベット順
rsort($fruits); // 逆順
Python:
# リストのソート
fruits.sort() # アルファベット順
fruits.sort(reverse=True) # 逆順
連想配列/辞書
PHP:
<?php
// 連想配列の作成
$person = [
"name" => "John",
"age" => 30,
"city" => "New York"
];
// 別の構文
$person = array(
"name" => "John",
"age" => 30,
"city" => "New York"
);
Python:
# 辞書の作成
person = {
"name": "John",
"age": 30,
"city": "New York"
}
PHP:
// 要素へのアクセス
echo $person["name"]; // "John"
$person["age"] = 31; // 更新
Python:
# 要素へのアクセス
print(person["name"]) # "John"
person["age"] = 31 # 更新
# 要素へのアクセス(キーが存在しない場合にエラーを避ける)
name = person.get("name") # "John"
phone = person.get("phone") # None
phone = person.get("phone", "Not available") # デフォルト値を提供
PHP:
// 要素の追加
$person["email"] = "john@example.com";
Python:
# 要素の追加
person["email"] = "john@example.com"
PHP:
// 要素の削除
unset($person["city"]);
Python:
# 要素の削除
del person["city"]
# または
city = person.pop("city", None) # キーが存在しない場合はNoneを返す
PHP:
// キーの存在確認
$exists = array_key_exists("name", $person); // true
$isset = isset($person["phone"]); // false
Python:
# キーの存在確認
exists = "name" in person # True
PHP:
// キーと値の取得
$keys = array_keys($person); // ["name", "age", "email"]
$values = array_values($person); // ["John", 31, "john@example.com"]
Python:
# キーと値の取得
keys = list(person.keys()) # ["name", "age", "email"]
values = list(person.values()) # ["John", 31, "john@example.com"]
PHP:
// 連想配列のループ
foreach ($person as $key => $value) {
echo "$key: $value\n";
}
Python:
# 辞書のループ
for key, value in person.items():
print(f"{key}: {value}")
リスト内包表記(Pythonの特徴)
PHP:
<?php
// PHPにはリスト内包表記に相当する機能はないが、array_mapで近い処理ができる
$numbers = [1, 2, 3, 4, 5];
$squares = array_map(function($n) { return $n * $n; }, $numbers);
// [1, 4, 9, 16, 25]
Python:
numbers = [1, 2, 3, 4, 5]
# リスト内包表記
squares = [n * n for n in numbers]
# [1, 4, 9, 16, 25]
PHP:
// フィルタリング
$evens = array_filter($numbers, function($n) { return $n % 2 == 0; });
// [2, 4]
Python:
# 条件付きリスト内包表記
evens = [n for n in numbers if n % 2 == 0]
# [2, 4]
PHP:
// 組み合わせ
$squared_evens = array_map(
function($n) { return $n * $n; },
array_filter($numbers, function($n) { return $n % 2 == 0; })
);
// [4, 16]
Python:
# 複合的なリスト内包表記
squared_evens = [n * n for n in numbers if n % 2 == 0]
# [4, 16]
# 辞書内包表記
squares_dict = {n: n * n for n in numbers}
# {1: 1, 2: 4, 3: 9, 4: 16, 5: 25}
日付と時間の操作
基本的な日付と時間
PHP:
<?php
// 現在の時刻(UNIXタイムスタンプ)
$now = time(); // 例:1640995200(秒単位)
Python:
import time
from datetime import datetime, timedelta
# 現在の時刻(UNIXタイムスタンプ)
now = time.time() # 例:1640995200.0(浮動小数点、秒単位)
PHP:
// タイムスタンプからフォーマット
$date_string = date("Y-m-d H:i:s", $now); // "2022-01-01 12:00:00"
Python:
# 現在の日時(datetimeオブジェクト)
dt_now = datetime.now() # 2022-01-01 12:00:00.000000
# タイムスタンプからフォーマット
date_string = datetime.fromtimestamp(now).strftime("%Y-%m-%d %H:%M:%S")
# "2022-01-01 12:00:00"
PHP:
// 文字列からタイムスタンプ
$timestamp = strtotime("2022-01-01 12:00:00"); // 1640995200
Python:
# 文字列からdatetimeオブジェクト
dt = datetime.strptime("2022-01-01 12:00:00", "%Y-%m-%d %H:%M:%S")
# datetimeオブジェクトからタイムスタンプ
timestamp = dt.timestamp() # 1640995200.0
PHP:
// 3日後のタイムスタンプ
$three_days_later = strtotime("+3 days");
Python:
# 3日後の日時
three_days_later = dt_now + timedelta(days=3)
PHP:
// 日付の比較
$is_future = $timestamp > time(); // 過去の日付なのでfalse
Python:
# 日付の比較
is_future = dt > datetime.now() # 過去の日付なのでFalse
DateTimeクラス/オブジェクト
PHP:
<?php
// DateTimeオブジェクトの作成
$now = new DateTime(); // 現在時刻
$date = new DateTime("2022-01-01 12:00:00"); // 特定の時刻
$timestamp_date = new DateTime("@" . time()); // タイムスタンプから
Python:
from datetime import datetime, timedelta, timezone
import pytz # タイムゾーン操作に便利なライブラリ
# datetimeオブジェクトの作成
now = datetime.now() # 現在時刻
date = datetime(2022, 1, 1, 12, 0, 0) # 特定の時刻
timestamp_date = datetime.fromtimestamp(time.time()) # タイムスタンプから
PHP:
// タイムゾーン設定
$tokyo = new DateTime("now", new DateTimeZone("Asia/Tokyo"));
Python:
# タイムゾーン設定
tokyo = datetime.now(pytz.timezone("Asia/Tokyo"))
PHP:
// フォーマット
$formatted = $date->format("Y年m月d日 H時i分s秒");
Python:
# フォーマット
formatted = date.strftime("%Y年%m月%d日 %H時%M分%S秒")
PHP:
// 日時の操作
$date->modify("+1 month"); // 1ヶ月後
$date->add(new DateInterval("P1Y2M")); // 1年2ヶ月後
$date->sub(new DateInterval("P10D")); // 10日前
Python:
# 日時の操作
one_month_later = date.replace(month=date.month + 1) # 月を直接指定
one_year_two_months_later = date.replace(
year=date.year + 1,
month=date.month + 2 if date.month < 11 else (date.month + 2) % 12
)
ten_days_ago = date - timedelta(days=10)
PHP:
// 日付間の差
$diff = $now->diff($date);
echo $diff->format("%y年%m月%d日の差");
Python:
# 日付間の差
diff = now - date
print(f"{diff.days}日の差") # より複雑な差分計算には追加の処理が必要
PHP:
// 日付の比較
$is_before = $date < $now;
Python:
# 日付の比較
is_before = date < now
ファイル操作
基本的なファイル操作
PHP:
<?php
// ファイルの読み込み(全体)
$content = file_get_contents("example.txt");
Python:
# ファイルの読み込み(全体)
with open("example.txt", "r", encoding="utf-8") as f:
content = f.read()
PHP:
// ファイルに書き込み
file_put_contents("output.txt", "Hello, World!", FILE_APPEND); // 追記
Python:
# ファイルに書き込み
with open("output.txt", "w", encoding="utf-8") as f:
f.write("Hello, World!")
# 追記モード
with open("output.txt", "a", encoding="utf-8") as f:
f.write("追加のテキスト")
PHP:
// ファイルを行単位で読み込み
$lines = file("example.txt", FILE_IGNORE_NEW_LINES | FILE_SKIP_EMPTY_LINES);
foreach ($lines as $line) {
echo $line;
}
Python:
# ファイルを行単位で読み込み
with open("example.txt", "r", encoding="utf-8") as f:
lines = f.readlines()
# または
with open("example.txt", "r", encoding="utf-8") as f:
for line in f:
print(line.strip())
PHP:
// ファイルの存在確認
if (file_exists("example.txt")) {
echo "ファイルが存在します";
}
Python:
# ファイルの存在確認
import os
if os.path.exists("example.txt"):
print("ファイルが存在します")
PHP:
// ファイルの削除
unlink("temporary.txt");
Python:
# ファイルの削除
import os
os.remove("temporary.txt")
PHP:
// ファイルのコピー
copy("source.txt", "destination.txt");
Python:
# ファイルのコピー
import shutil
shutil.copy("source.txt", "destination.txt")
PHP:
// ファイルの移動/名前変更
rename("old.txt", "new.txt");
Python:
# ファイルの移動/名前変更
import os
os.rename("old.txt", "new.txt")
ディレクトリ操作
PHP:
<?php
// ディレクトリの作成
mkdir("new_folder", 0755);
Python:
import os
import shutil
import glob
# ディレクトリの作成
os.mkdir("new_folder")
PHP:
// 再帰的にディレクトリを作成
mkdir("path/to/new/folder", 0755, true);
Python:
# 再帰的にディレクトリを作成
os.makedirs("path/to/new/folder", exist_ok=True)
PHP:
// ディレクトリ内のファイル一覧
$files = scandir("folder");
Python:
# ディレクトリ内のファイル一覧
files = os.listdir("folder")
PHP:
// 特定パターンのファイルを検索
$php_files = glob("*.php");
Python:
# 特定パターンのファイルを検索
py_files = glob.glob("*.py")
PHP:
// ディレクトリの削除
rmdir("empty_folder"); // 空のディレクトリのみ削除可能
Python:
# ディレクトリの削除
os.rmdir("empty_folder") # 空のディレクトリのみ削除可能
PHP:
// ディレクトリとその中身を再帰的に削除するには専用関数が必要
function rmdir_recursive($dir) {
$files = array_diff(scandir($dir), array('.','..'));
foreach ($files as $file) {
$path = "$dir/$file";
is_dir($path) ? rmdir_recursive($path) : unlink($path);
}
return rmdir($dir);
}
Python:
# ディレクトリとその中身を再帰的に削除
shutil.rmtree("folder") # 注意: 取り消せない操作
正規表現
パターンマッチング
PHP:
<?php
// 正規表現でマッチング
$text = "Email: example@example.com";
$pattern = '/[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}/i';
if (preg_match($pattern, $text, $matches)) {
echo "マッチしました: " . $matches[0]; // "example@example.com"
}
Python:
import re
# 正規表現でマッチング
text = "Email: example@example.com"
pattern = r'[a-z0-9._%+-]+@[a-z0-9.-]+\.[a-z]{2,}'
match = re.search(pattern, text, re.IGNORECASE)
if match:
print(f"マッチしました: {match.group(0)}") # "example@example.com"
PHP:
// すべてのマッチを取得
$text = "Contact us at info@example.com or support@example.org";
preg_match_all($pattern, $text, $matches);
print_r($matches[0]); // ["info@example.com", "support@example.org"]
Python:
# すべてのマッチを取得
text = "Contact us at info@example.com or support@example.org"
matches = re.findall(pattern, text, re.IGNORECASE)
print(matches) # ["info@example.com", "support@example.org"]
PHP:
// 正規表現による置換
$replaced = preg_replace($pattern, "[EMAIL]", $text);
// "Contact us at [EMAIL] or [EMAIL]"
Python:
# 正規表現による置換
replaced = re.sub(pattern, "[EMAIL]", text, flags=re.IGNORECASE)
# "Contact us at [EMAIL] or [EMAIL]"
PHP:
// 複雑な置換(コールバック関数を使用)
$result = preg_replace_callback(
$pattern,
function ($match) {
return strtoupper($match[0]);
},
$text
);
// "Contact us at INFO@EXAMPLE.COM or SUPPORT@EXAMPLE.ORG"
Python:
# 複雑な置換(関数を使用)
def upper_email(match):
return match.group(0).upper()
result = re.sub(pattern, upper_email, text, flags=re.IGNORECASE)
# "Contact us at INFO@EXAMPLE.COM or SUPPORT@EXAMPLE.ORG"
よく使う便利機能
配列操作
PHP:
<?php
$numbers = [1, 2, 3, 4, 5];
// map: 各要素に処理を適用
$doubled = array_map(function($n) { return $n * 2; }, $numbers);
// [2, 4, 6, 8, 10]
Python:
numbers = [1, 2, 3, 4, 5]
# map: 各要素に処理を適用
doubled = list(map(lambda n: n * 2, numbers))
# または
doubled = [n * 2 for n in numbers]
# [2, 4, 6, 8, 10]
PHP:
// filter: 条件に合う要素のみ抽出
$evens = array_filter($numbers, function($n) { return $n % 2 == 0; });
// [2, 4]
Python:
# filter: 条件に合う要素のみ抽出
evens = list(filter(lambda n: n % 2 == 0, numbers))
# または
evens = [n for n in numbers if n % 2 == 0]
# [2, 4]
PHP:
// reduce: 要素を集約
$sum = array_reduce($numbers, function($carry, $n) { return $carry + $n; }, 0);
// 15
Python:
# reduce: 要素を集約
from functools import reduce
sum_value = reduce(lambda x, y: x + y, numbers, 0)
# または単にPythonの組み込み関数
sum_value = sum(numbers)
# 15
PHP:
// 配列からキーと値のペアを取得
$fruits = ["apple" => "red", "banana" => "yellow"];
foreach ($fruits as $name => $color) {
echo "$name is $color";
}
Python:
# 辞書からキーと値のペアを取得
fruits = {"apple": "red", "banana": "yellow"}
for name, color in fruits.items():
print(f"{name} is {color}")
JSON処理
PHP:
<?php
// 配列/オブジェクトをJSONに変換
$data = ["name" => "John", "age" => 30];
$json = json_encode($data);
// {"name":"John","age":30}
Python:
import json
# 辞書をJSONに変換
data = {"name": "John", "age": 30}
json_str = json.dumps(data)
# {"name": "John", "age": 30}
PHP:
// 整形したJSON
$json_pretty = json_encode($data, JSON_PRETTY_PRINT);
Python:
# 整形したJSON
json_pretty = json.dumps(data, indent=4)
PHP:
// JSONを配列/オブジェクトに変換
$decoded = json_decode($json, true); // 連想配列として
$object = json_decode($json); // オブジェクトとして
Python:
# JSONを辞書に変換
decoded = json.loads(json_str)
ランダム値の生成
PHP:
<?php
// 乱数生成
$random = rand(1, 100); // 1から100までの整数
Python:
import random
import string
# 乱数生成
random_num = random.randint(1, 100) # 1から100までの整数
PHP:
// PHP 7以降の安全な乱数
$secure_random = random_int(1, 100);
Python:
# Pythonの標準randintは既に暗号論的に十分な乱数ではない
# 暗号論的に安全な乱数が必要な場合は secrets モジュールを使用
import secrets
secure_random = secrets.randbelow(100) + 1 # 1から100までの整数
PHP:
// 配列からランダムに要素を選択
$fruits = ["apple", "banana", "orange"];
$random_fruit = $fruits[array_rand($fruits)];
Python:
# 配列からランダムに要素を選択
fruits = ["apple", "banana", "orange"]
random_fruit = random.choice(fruits)
PHP:
// ランダムな文字列生成
function generate_random_string($length = 10) {
$characters = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ';
$random_string = '';
for ($i = 0; $i < $length; $i++) {
$random_string .= $characters[rand(0, strlen($characters) - 1)];
}
return $random_string;
}
Python:
# ランダムな文字列生成
def generate_random_string(length=10):
characters = string.ascii_letters + string.digits
return ''.join(random.choice(characters) for _ in range(length))
暗号化とハッシュ
PHP:
<?php
// パスワードのハッシュ化(推奨方法)
$password = "secret123";
$hash = password_hash($password, PASSWORD_DEFAULT);
Python:
import hashlib
import os
import binascii
import bcrypt # 外部ライブラリ
# パスワードのハッシュ化(bcryptを使用)
password = "secret123"
salt = bcrypt.gensalt()
hashed = bcrypt.hashpw(password.encode(), salt)
PHP:
// ハッシュの検証
$is_valid = password_verify($password, $hash); // true
Python:
# ハッシュの検証
is_valid = bcrypt.checkpw(password.encode(), hashed) # True
PHP:
// MD5ハッシュ(非推奨)
$md5 = md5($password);
Python:
# MD5ハッシュ(非推奨)
md5 = hashlib.md5(password.encode()).hexdigest()
PHP:
// SHA-256ハッシュ
$sha256 = hash('sha256', $password);
Python:
# SHA-256ハッシュ
sha256 = hashlib.sha256(password.encode()).hexdigest()
PHP:
// ランダムなバイト列を生成
$bytes = random_bytes(16);
$hex = bin2hex($bytes);
Python:
# ランダムなバイト列を生成
bytes_val = os.urandom(16)
hex_val = binascii.hexlify(bytes_val).decode()
デバッグ情報の出力
PHP:
<?php
// 変数の詳細情報を出力
$data = ["name" => "John", "age" => 30];
var_dump($data);
Python:
# 変数の詳細情報を出力
data = {"name": "John", "age": 30}
print(data)
PHP:
// 読みやすい形式で出力
print_r($data);
Python:
# 詳細な情報表示
import pprint
pprint.pprint(data)
PHP:
// 変数の型と値を取得
$type = gettype($data); // "array"
$is_array = is_array($data); // true
Python:
# 変数の型を取得
type_val = type(data) # <class 'dict'>
is_dict = isinstance(data, dict) # True
PHP:
// バックトレース情報
debug_print_backtrace();
$trace = debug_backtrace();
Python:
# スタックトレース情報
import traceback
traceback.print_stack()
stack = traceback.format_stack()
まとめ
PHPとPythonは構文面では多くの違いがありますが、根底にある概念は比較的類似しています。しかし、設計思想や実行環境の違いにより、ベストプラクティスや一般的なパターンには注意すべき違いがあります。
PHPからPythonに移行する際の主なポイント:
-
構文の違い: 変数の接頭辞 (
$
) の有無、ブロックの区切り方(波括弧 vs インデント) - 命名規則: PHP(camelCase/PascalCase)vs Python(snake_case)
- 配列と辞書: PHPの配列は多目的(順序付き配列と連想配列の両方)、Pythonではリストと辞書に分かれている
- クラスとオブジェクト指向: どちらも強力なOOP機能を提供しているが、アクセス修飾子やトレイト/ミックスインの扱いに違いがある
-
文字列操作: PHPのマルチバイト対応関数(
mb_*
)vs Pythonの標準Unicode対応 - Python固有の機能: リスト内包表記、ジェネレータ、デコレータなど
どちらの言語も幅広い用途に適していますが、パフォーマンス特性や使用環境によって、それぞれの得意分野があります。PHPはWebアプリケーション開発に特化している一方、Pythonはデータ分析、機械学習、自動化スクリプトなど、より幅広い領域で活用されています。
両方の言語を学ぶことで、問題解決のアプローチの幅が広がり、より強力なツールセットを身につけることができます。
Discussion