こんにちは!今回は、PHPの標準関数であるstrrev()について詳しく解説していきます。文字列を逆順にする、シンプルだけど便利な関数です!
strrev関数とは?
strrev()関数は、文字列を反転(逆順に)する関数です。
“string reverse”の略で、文字列の最後の文字が最初に、最初の文字が最後になります。回文のチェックやデータの検証など、意外と使い道がある関数です!
基本的な構文
strrev(string $string): string
- $string: 反転する文字列
- 戻り値: 反転された文字列
基本的な使用例
シンプルな反転
// 英数字の反転
$text = "Hello";
echo strrev($text) . "\n";
// 出力: olleH
// 数字の反転
$number = "12345";
echo strrev($number) . "\n";
// 出力: 54321
// 文章の反転
$sentence = "Hello World";
echo strrev($sentence) . "\n";
// 出力: dlroW olleH
空文字列と1文字
// 空文字列
$empty = "";
echo strrev($empty) . "\n";
// 出力: (空)
// 1文字
$single = "A";
echo strrev($single) . "\n";
// 出力: A
マルチバイト文字の扱い
// 日本語(注意が必要)
$japanese = "こんにちは";
echo strrev($japanese) . "\n";
// 出力: は���に���ん���こ���(文字化けする)
// マルチバイト対応の反転が必要な場合
function mb_strrev($str, $encoding = 'UTF-8') {
$length = mb_strlen($str, $encoding);
$reversed = '';
for ($i = $length - 1; $i >= 0; $i--) {
$reversed .= mb_substr($str, $i, 1, $encoding);
}
return $reversed;
}
echo mb_strrev("こんにちは") . "\n";
// 出力: はちにんこ
実践的な使用例
例1: 回文(パリンドローム)のチェック
class PalindromeChecker {
/**
* 回文かどうかチェック
*/
public static function isPalindrome($text) {
// 大文字小文字を統一
$normalized = strtolower($text);
// 空白と記号を除去
$cleaned = preg_replace('/[^a-z0-9]/', '', $normalized);
// 反転したものと比較
return $cleaned === strrev($cleaned);
}
/**
* 回文かどうかチェック(完全一致)
*/
public static function isStrictPalindrome($text) {
return $text === strrev($text);
}
/**
* 数値回文のチェック
*/
public static function isNumericPalindrome($number) {
$str = (string)$number;
return $str === strrev($str);
}
/**
* 単語単位の回文チェック
*/
public static function isWordPalindrome($sentence) {
$words = preg_split('/\s+/', trim($sentence));
$reversed = array_reverse($words);
return $words === $reversed;
}
/**
* マルチバイト対応回文チェック
*/
public static function isMbPalindrome($text, $encoding = 'UTF-8') {
$length = mb_strlen($text, $encoding);
$reversed = '';
for ($i = $length - 1; $i >= 0; $i--) {
$reversed .= mb_substr($text, $i, 1, $encoding);
}
return $text === $reversed;
}
}
// 使用例
echo "=== 回文チェック ===\n";
$words = [
'racecar',
'madam',
'hello',
'A man a plan a canal Panama',
'noon',
'world'
];
foreach ($words as $word) {
$isPalindrome = PalindromeChecker::isPalindrome($word);
echo "{$word}: " . ($isPalindrome ? '回文' : '非回文') . "\n";
}
echo "\n=== 数値回文 ===\n";
$numbers = [12321, 12345, 1001, 9009];
foreach ($numbers as $num) {
$isPalindrome = PalindromeChecker::isNumericPalindrome($num);
echo "{$num}: " . ($isPalindrome ? '回文' : '非回文') . "\n";
}
echo "\n=== 日本語回文 ===\n";
$japanese = ['しんぶんし', 'たけやぶやけた', 'こんにちは'];
foreach ($japanese as $word) {
$isPalindrome = PalindromeChecker::isMbPalindrome($word);
echo "{$word}: " . ($isPalindrome ? '回文' : '非回文') . "\n";
}
例2: 文字列の比較と検証
class StringValidator {
/**
* 対称性をチェック
*/
public static function isSymmetric($text) {
return $text === strrev($text);
}
/**
* 反転してもユニークかチェック
*/
public static function isUniqueWhenReversed($text) {
$reversed = strrev($text);
return $text !== $reversed;
}
/**
* 反転ペアを生成
*/
public static function generateReversePair($text) {
return [
'original' => $text,
'reversed' => strrev($text)
];
}
/**
* 2つの文字列が反転関係にあるかチェック
*/
public static function areReverseOfEachOther($str1, $str2) {
return $str1 === strrev($str2);
}
/**
* 反転して同じ値になるか検証
*/
public static function validateSymmetry($data) {
$results = [];
foreach ($data as $item) {
$results[$item] = [
'original' => $item,
'reversed' => strrev($item),
'is_symmetric' => self::isSymmetric($item)
];
}
return $results;
}
}
// 使用例
echo "=== 対称性チェック ===\n";
$strings = ['12321', '12345', 'abcba', 'hello'];
foreach ($strings as $str) {
$symmetric = StringValidator::isSymmetric($str);
echo "{$str}: " . ($symmetric ? '対称' : '非対称') . "\n";
}
echo "\n=== 反転ペア ===\n";
$pairs = StringValidator::generateReversePair('hello');
print_r($pairs);
echo "\n=== 反転関係チェック ===\n";
var_dump(StringValidator::areReverseOfEachOther('abc', 'cba')); // true
var_dump(StringValidator::areReverseOfEachOther('abc', 'xyz')); // false
例3: データのエンコード・デコード
class SimpleEncoder {
/**
* 簡易エンコード(反転 + Base64)
*/
public static function encode($data) {
$reversed = strrev($data);
return base64_encode($reversed);
}
/**
* 簡易デコード
*/
public static function decode($encoded) {
$decoded = base64_decode($encoded);
return strrev($decoded);
}
/**
* 2重反転エンコード
*/
public static function doubleReverse($text) {
$first = strrev($text);
$second = strrev($first);
return $second; // 元に戻る
}
/**
* チェックサム生成(簡易版)
*/
public static function generateChecksum($data) {
$combined = $data . strrev($data);
return md5($combined);
}
/**
* 難読化
*/
public static function obfuscate($text) {
$reversed = strrev($text);
$encoded = base64_encode($reversed);
return str_rot13($encoded);
}
/**
* 難読化解除
*/
public static function deobfuscate($obfuscated) {
$unrotated = str_rot13($obfuscated);
$decoded = base64_decode($unrotated);
return strrev($decoded);
}
}
// 使用例
echo "=== エンコード・デコード ===\n";
$original = "secret message";
$encoded = SimpleEncoder::encode($original);
$decoded = SimpleEncoder::decode($encoded);
echo "元のデータ: {$original}\n";
echo "エンコード: {$encoded}\n";
echo "デコード: {$decoded}\n";
echo "\n=== チェックサム ===\n";
$data = "important data";
$checksum = SimpleEncoder::generateChecksum($data);
echo "データ: {$data}\n";
echo "チェックサム: {$checksum}\n";
echo "\n=== 難読化 ===\n";
$text = "confidential";
$obfuscated = SimpleEncoder::obfuscate($text);
$deobfuscated = SimpleEncoder::deobfuscate($obfuscated);
echo "元: {$text}\n";
echo "難読化: {$obfuscated}\n";
echo "復元: {$deobfuscated}\n";
例4: 数値処理
class NumberReverser {
/**
* 数値を反転
*/
public static function reverseNumber($number) {
$str = (string)abs($number);
$reversed = strrev($str);
$result = (int)$reversed;
return $number < 0 ? -$result : $result;
}
/**
* 反転した数値を加算
*/
public static function addReversed($number) {
$reversed = self::reverseNumber($number);
return $number + $reversed;
}
/**
* 196問題をチェック(回文になるまで加算)
*/
public static function findPalindrome($number, $maxIterations = 100) {
$steps = [];
$current = $number;
for ($i = 0; $i < $maxIterations; $i++) {
$reversed = self::reverseNumber($current);
$steps[] = [
'number' => $current,
'reversed' => $reversed,
'sum' => $current + $reversed
];
if (PalindromeChecker::isNumericPalindrome($current)) {
return [
'found' => true,
'iterations' => $i,
'result' => $current,
'steps' => $steps
];
}
$current = $current + $reversed;
}
return [
'found' => false,
'iterations' => $maxIterations,
'steps' => $steps
];
}
/**
* 数値のミラーリング
*/
public static function mirrorNumber($number) {
$str = (string)$number;
return $str . strrev($str);
}
}
// 使用例
echo "=== 数値反転 ===\n";
$numbers = [123, 9876, -456, 1000];
foreach ($numbers as $num) {
$reversed = NumberReverser::reverseNumber($num);
echo "{$num} → {$reversed}\n";
}
echo "\n=== 反転数値を加算 ===\n";
$num = 123;
$sum = NumberReverser::addReversed($num);
echo "{$num} + " . NumberReverser::reverseNumber($num) . " = {$sum}\n";
echo "\n=== 回文を見つける ===\n";
$result = NumberReverser::findPalindrome(89, 10);
if ($result['found']) {
echo "回文発見: {$result['result']} ({$result['iterations']}ステップ)\n";
}
echo "\n=== ミラー数値 ===\n";
echo NumberReverser::mirrorNumber(123) . "\n"; // 123321
例5: テキスト処理
class TextProcessor {
/**
* 単語を反転
*/
public static function reverseWords($sentence) {
$words = explode(' ', $sentence);
$reversed = array_map('strrev', $words);
return implode(' ', $reversed);
}
/**
* 文の順序を反転
*/
public static function reverseSentenceOrder($text) {
return strrev($text);
}
/**
* 各行を反転
*/
public static function reverseLines($text) {
$lines = explode("\n", $text);
$reversed = array_map('strrev', $lines);
return implode("\n", $reversed);
}
/**
* 母音と子音の位置を確認
*/
public static function analyzeReversed($word) {
$reversed = strrev($word);
return [
'original' => $word,
'reversed' => $reversed,
'length' => strlen($word),
'same' => $word === $reversed
];
}
/**
* アナグラムチェックの補助
*/
public static function sortedString($text) {
$chars = str_split(strtolower($text));
sort($chars);
return implode('', $chars);
}
}
// 使用例
echo "=== 単語反転 ===\n";
$sentence = "Hello World from PHP";
echo "元: {$sentence}\n";
echo "反転: " . TextProcessor::reverseWords($sentence) . "\n";
// olleH dlroW morf PHP
echo "\n=== 文全体反転 ===\n";
echo TextProcessor::reverseSentenceOrder($sentence) . "\n";
// PHP morf dlroW olleH
$multiline = "Line 1\nLine 2\nLine 3";
echo "\n=== 各行反転 ===\n";
echo TextProcessor::reverseLines($multiline) . "\n";
echo "\n=== 分析 ===\n";
$analysis = TextProcessor::analyzeReversed('racecar');
print_r($analysis);
例6: ゲームやパズル
class WordGame {
/**
* リバースワードゲーム
*/
public static function createReverseChallenge($word) {
return [
'hint' => strrev($word),
'answer' => $word,
'length' => strlen($word)
];
}
/**
* ヒントを生成
*/
public static function generateHint($word, $revealCount = 2) {
$reversed = strrev($word);
$hint = str_repeat('*', strlen($word));
// 最初と最後の文字を表示
if (strlen($word) > 0) {
$hint[0] = $word[0];
}
if (strlen($word) > 1) {
$hint[strlen($hint) - 1] = $word[strlen($word) - 1];
}
return [
'hint' => $hint,
'reversed' => $reversed,
'length' => strlen($word)
];
}
/**
* スコア計算
*/
public static function calculateScore($word, $timeTaken) {
$baseScore = strlen($word) * 10;
$timeBonus = max(0, 60 - $timeTaken) * 2;
$isPalindrome = PalindromeChecker::isPalindrome($word);
$palindromeBonus = $isPalindrome ? 50 : 0;
return $baseScore + $timeBonus + $palindromeBonus;
}
}
// 使用例
echo "=== リバースワードゲーム ===\n";
$words = ['elephant', 'computer', 'racecar'];
foreach ($words as $word) {
$challenge = WordGame::createReverseChallenge($word);
echo "\nヒント(反転): {$challenge['hint']}\n";
echo "文字数: {$challenge['length']}\n";
echo "答え: {$challenge['answer']}\n";
$hint = WordGame::generateHint($word);
echo "部分ヒント: {$hint['hint']}\n";
}
例7: セキュリティとハッシュ
class SecurityHelper {
/**
* 反転ハッシュ生成
*/
public static function reverseHash($data) {
$reversed = strrev($data);
$hash = hash('sha256', $reversed);
return $hash;
}
/**
* 二重ハッシュ
*/
public static function doubleHash($data) {
$hash1 = hash('sha256', $data);
$hash2 = hash('sha256', strrev($data));
return hash('sha256', $hash1 . $hash2);
}
/**
* トークン生成
*/
public static function generateToken($seed) {
$timestamp = time();
$random = bin2hex(random_bytes(16));
$combined = $seed . $timestamp . $random;
$forward = hash('sha256', $combined);
$backward = hash('sha256', strrev($combined));
return substr($forward, 0, 16) . substr($backward, 0, 16);
}
/**
* チェックサム検証
*/
public static function verifyChecksum($data, $checksum) {
$calculated = self::reverseHash($data);
return hash_equals($checksum, $calculated);
}
}
// 使用例
echo "=== セキュリティ処理 ===\n";
$data = "sensitive information";
echo "データ: {$data}\n";
echo "反転ハッシュ: " . SecurityHelper::reverseHash($data) . "\n";
echo "二重ハッシュ: " . SecurityHelper::doubleHash($data) . "\n";
$token = SecurityHelper::generateToken('user123');
echo "\nトークン: {$token}\n";
例8: ファイル名処理
class FilenameHelper {
/**
* 拡張子を保ったまま名前を反転
*/
public static function reverseBasename($filename) {
$info = pathinfo($filename);
$basename = $info['filename'];
$extension = isset($info['extension']) ? '.' . $info['extension'] : '';
return strrev($basename) . $extension;
}
/**
* ユニークなファイル名を生成
*/
public static function generateUniqueName($originalName) {
$info = pathinfo($originalName);
$basename = $info['filename'];
$extension = isset($info['extension']) ? '.' . $info['extension'] : '';
$reversed = strrev($basename);
$timestamp = time();
return "{$basename}_{$reversed}_{$timestamp}{$extension}";
}
/**
* ペアファイル名を生成
*/
public static function generatePairName($filename) {
$reversed = strrev(pathinfo($filename, PATHINFO_FILENAME));
$extension = pathinfo($filename, PATHINFO_EXTENSION);
return $reversed . ($extension ? '.' . $extension : '');
}
}
// 使用例
echo "=== ファイル名処理 ===\n";
$files = ['document.txt', 'photo.jpg', 'backup'];
foreach ($files as $file) {
echo "\n元: {$file}\n";
echo "反転: " . FilenameHelper::reverseBasename($file) . "\n";
echo "ユニーク: " . FilenameHelper::generateUniqueName($file) . "\n";
echo "ペア: " . FilenameHelper::generatePairName($file) . "\n";
}
パフォーマンスの考慮
// 大量の文字列反転
$text = str_repeat("abcdefghijklmnopqrstuvwxyz", 1000);
// strrev()
$start = microtime(true);
for ($i = 0; $i < 10000; $i++) {
strrev($text);
}
$time1 = microtime(true) - $start;
// 手動反転
$start = microtime(true);
for ($i = 0; $i < 10000; $i++) {
$reversed = '';
for ($j = strlen($text) - 1; $j >= 0; $j--) {
$reversed .= $text[$j];
}
}
$time2 = microtime(true) - $start;
echo "strrev(): {$time1}秒\n";
echo "手動反転: {$time2}秒\n";
// strrev()は非常に高速に最適化されている
まとめ
strrev()関数の特徴をまとめると:
できること:
- 文字列の反転
- 回文のチェック
- 数値の反転
- データのエンコード補助
推奨される使用場面:
- 回文(パリンドローム)チェック
- 文字列の対称性検証
- 簡易的なエンコード
- 数値処理
- ゲームやパズル
- ユニークなID生成
注意点:
- マルチバイト文字(日本語など)では正しく動作しない
- マルチバイト対応が必要な場合は
mb_substr()を使った独自実装が必要 - セキュリティ目的のエンコードには不十分
マルチバイト対応:
function mb_strrev($str, $encoding = 'UTF-8') {
$length = mb_strlen($str, $encoding);
$reversed = '';
for ($i = $length - 1; $i >= 0; $i--) {
$reversed .= mb_substr($str, $i, 1, $encoding);
}
return $reversed;
}
関連関数:
str_split(): 文字列を配列に分割array_reverse(): 配列を反転substr(): 部分文字列の取得
パフォーマンス:
- 非常に高速(C言語レベルで最適化)
- 大量のデータでも効率的
strrev()はシンプルながら様々な用途に使える関数です。特に回文チェックや数値処理、ゲーム実装などで活躍します。マルチバイト文字を扱う場合は独自実装が必要ですが、ASCII文字列なら非常に効率的に動作します!
