PHPの基礎 - 文字列
概要
PHPでは複数のデータ型が存在するが、文字の集合を表すために使用されるデータ型が文字列である。
ここでは、文字列の取り扱いを記載する。
文字列リテラル
文字列を記述する場合、文字の集合をシングルクオーテーション'
またはダブルクオーテーション"
で囲む。
なお、''
で囲む場合と""
で囲む場合では、データの扱いが異なる。(詳細は、次のセクションに記載する)
'文字列' "文字列"
複数行に渡る文字列を作成するには、ヒアドキュメントを使用することもできる。
ヒアドキュメントは、<<< <ID名>で始まり<ID名>で終わる間に記述する。ID名は、任意の文字列が指定できる。
また、ヒアドキュメントでは、シングルクオーテーション'
、ダブルクオーテーション"
、空白も文字として扱われる。
<<< ID 文字列1 文字列2 文字列3 ID
以下の例では、ID名をDocumentとしている。
<<< Document
こんにちは。<br />
お元気ですか?
Document
文字列の連結
ドット演算子 (.)
文字列と他の文字列を連結して新しい文字列を作成するには、.
を使用する。
単純な文字列結合には、.
や.=
が理解しやすい。
'文字列1'.'文字列2'
以下の例では、2つの文字列を連結して出力している。
print 'こんにちは。'.'お元気ですか?';
$name = '佐藤';
print $name.'さん。こんにちは。';
また、連結した文字列を変数に格納することもできる。
$name = '佐藤' . 'さん';
複合代入演算子 (.=)
単純な文字列結合には、.
や.=
が理解しやすい。
$str = "Hello";
$str .= " World"; // "Hello World"
ダブルクォート内での変数展開
変数を文字列に埋め込む場合は変数展開がよい。
$name = "World";
$greeting = "Hello $name"; // "Hello World"
中括弧を使用した変数展開
変数を文字列に埋め込む場合は変数展開がよい。
$name = "World";
$greeting = "Hello {$name}"; // "Hello World"
sprintf関数の使用
フォーマットを指定する場合はsprintfがよい。
$name = "World";
$greeting = sprintf("Hello %s", $name); // "Hello World"
implode関数 (配列の要素を結合)
配列の要素を結合する場合は、implode
関数を使用する。
$words = ["Hello", "World"];
$greeting = implode(" ", $words); // "Hello World"
文字列の出力(echo, print)
文字列を出力するには、echo
とprint
が存在する。
echo
の書式は、以下の通りである。
echo "" void echo(string $arg1 [, string $... ])
echo
は引数に指定した文字列を出力する。
複数の文字列を続けて出力する場合、カンマ,
で区切って文字列を指定する。
echo 'こんにちは';
echo '出身地:', '東京都';
厳密にいうと、echo
は関数ではなくPHPの言語構造の1つである。
そのため、引数を括弧で括る必要はなく、関数のように括弧で括って記述することもできる。
ただし、複数の文字列を引数に指定する場合、括弧で括らない方がよい。
echo('こんにちは');
print
の書式は、以下の通りである。
print "" int print(string $arg)
print
は、引数に指定した文字列を出力する。echo
とは異なり、複数の引数を指定できない。
また、戻り値として常に1を返す。
print 'こんにちは';
print
もecho
と同様、関数ではなくPHPの言語構造の1つである。
そのため、引数を括弧で括る必要はなく、関数のように括弧で括って記述することもできる。
print('こんにちは');
エスケープシーケンス
文字列として入力できない特殊な文字(改行文字等)が存在する。
このような特殊な文字を入力するために、\記号 + 1文字等を使用して、特殊文字等を記述することができる。
このような特殊な記述方法をエスケープシーケンスと呼ぶ。
エスケープシーケンスとして用意されているものには、以下のようなものがある。
¥n 改行 ¥r キャリッジリターン ¥t タブ ¥¥ ¥文字 ¥$ $文字 ¥( 左括弧 ¥) 右括弧 ¥[ 左括弧 ¥] 右括弧 ¥' シングルクオーテーション ¥" ダブルクオーテーション ¥nnn 8 進数表記 ¥xnn 16 進数表記
エスケープシーケンスは、ダブルクオーテーションで囲まれた文字列の場合にのみ意味を持つ。
例えば、以下のように使用する。
print "こんにちは¥n";
print "名前は¥"伊藤¥"です"; // ダブルクオーテーションで囲まれた文字列の中で"を出力する場合
また、ダブルクオーテーションで囲まれた文字列の中で¥文字を出力する場合、¥¥
と記述する。
※注意
シングルクオーテーションで囲まれた文字列の中でも、以下の2つだけはエスケープシーケンスとして扱われる。
¥' シングルクオーテーション ¥¥ ¥文字
print '出身地は¥'大阪¥'です';
文字列の抽出
mb_substr関数は、日本語等のマルチバイト文字列を安全に扱うための関数である。
mb_substrの主な使用パターンを以下に示す。
- 基本的な文字列の切り出し
- 末尾からの文字列取得
- 途中からの文字列取得
- エンコーディングを指定した使用方法
※注意
- 必要に応じて適切な文字エンコーディングを指定する。
- 文字列の長さを確認する場合は、mb_strlen関数を使用する。
- 負の位置指定も可能だが、慎重に使用する。
抽出の基本
$text = "こんにちは世界";
$substr = mb_substr($text, 0, 3); // "こんに" が取得される
echo $substr . "\n";
負の開始位置を使用 (末尾から数える)
$text = "プログラミング";
$substr = mb_substr($text, -3); // "ミング"が取得される
echo $substr . "\n";
文字列の途中から指定文字数を取得
$text = "私はPHPが好きです";
$substr = mb_substr($text, 2, 3); // "PHP" が取得される
echo $substr . "\n";
文字エンコーディングの指定
$text = "안녕하세요"; // 韓国語
$substr = mb_substr($text, 0, 2, 'UTF-8'); // "안녕"が取得される
echo $substr . "\n";
長い文字列を省略して表示 (例: ブログの要約等)
function createExcerpt(&$text, $length = 100)
{
if (mb_strlen($text) > $length) {
return mb_substr($text, 0, $length) . '...';
}
return $text;
}
$longText = "これは非常に長い文章である。途中で切られて...という形で表示される。";
echo createExcerpt($longText, 10); // "これは非常に長..." が表示される
文字列の検索
mb_strpos関数は、マルチバイト文字列の中から特定の文字列が最初に現れる位置を検索する関数である。
日本語等のマルチバイト文字を含む文字列で特に重要である。
# 戻り値 文字列が見つかった場合 : 最初に現れる位置 (0から始まる) 見つからない場合 : false
# 引数 第1引数 : 検索対象の文字列 第2引数 : 検索する文字列 第3引数 : 検索開始位置 (オプション) 第4引数 : 文字エンコーディング (オプション)
使用するシーンを以下に示す。
- 文字列の存在の確認
- 特定の文字列間のテキスト抽出
- タグやマーカーの位置検出
- 文字列の分割処理
※注意
- 戻り値のチェックには必ず
===
を使用する。(0とfalseを区別するため) - 必要に応じて適切な文字エンコーディングを指定する。
- 大文字・小文字を区別するため、必要に応じてカスタム関数を作成する。
基本的な使用例
$text = "こんにちは世界";
$position = mb_strpos($text, "世界"); // 5が返される
echo "Position: " . $position . "\n";
検索開始位置の指定
$text = "PHPはとても楽しい。PHPで開発しましょう。";
$position = mb_strpos($text, "PHP", 5); // 12が返される (2番目のPHPの位置)
echo "Second PHP position: " . $position . "\n";
文字が見つからない場合の処理
$text = "こんにちは世界";
$position = mb_strpos($text, "さようなら");
if ($position === false) {
echo "文字列が見つかりませんでした。\n";
}
文字エンコーディングの指定
$text = "안녕하세요"; // 韓国語
$position = mb_strpos($text, "하", 0, 'UTF-8');
echo "Korean character position: " . $position . "\n";
実践的な使用例 : 文字列の存在の確認と部分取得
function extractText($text, $start_marker, $end_marker)
{
$start_pos = mb_strpos($text, $start_marker);
if ($start_pos === false) {
return null;
}
$start_pos += mb_strlen($start_marker);
$end_pos = mb_strpos($text, $end_marker, $start_pos);
if ($end_pos === false) {
return null;
}
return mb_substr($text, $start_pos, $end_pos - $start_pos);
}
$text = "【タイトル】PHPプログラミング【終了】";
$content = extractText($text, "【タイトル】", "【終了】");
echo "Extracted content: " . $content . "\n"; // "PHPプログラミング" が出力される
大文字・小文字を区別しない検索
function mb_stripos_custom($haystack, $needle)
{
return mb_strpos(
mb_strtolower($haystack),
mb_strtolower($needle)
);
}
$text = "PHPとphpは同じ意味です。";
$position = mb_stripos_custom($text, "php");
echo "Case-insensitive position: " . $position . "\n";
文字列の置換
str_replace関数は文字列の置換を行う関数である。
str_replace($search, $replace, $subject [, &$count]) # 第1引数 : 検索する文字列または配列 # 第2引数 : 置換する文字列または配列 # 第3引数 : 対象の文字列または配列 # 第4引数 : 置換が行われた回数 (オプション)
str_replace関数の特徴を以下に示す。
- 大文字・小文字を区別する。
区別しない場合は、str_ireplace関数を使用する。 - 配列での複数置換が可能である。
- 文字列だけでなく配列も処理可能である。
- マルチバイト文字 (日本語等) も処理できる。
注意
- 配列を使用する場合、search配列とreplace配列の要素数が異なる場合は空文字が使用される。
- パフォーマンスを考慮する場合は、正規表現 (preg_replace関数) の使用も検討する。
- 大量のデータを処理する場合はメモリ使用量に注意する。
一般的な使用シーンを以下に示す。
- テキストの整形
- HTMLの処理
- ファイル名の処理
- データのクリーニング
- フォーマット変換
置換の基本
$text = "Hello World";
$result = str_replace("World", "PHP", $text);
echo $result . "\n"; // "Hello PHP"
日本語 (マルチバイト文字) の置換
$text = "こんにちは世界";
$result = str_replace("世界", "みなさん", $text);
echo $result . "\n"; // "こんにちはみなさん"
複数の文字列を置換
$text = "りんごとバナナとみかん";
$search = ["りんご", "バナナ", "みかん"];
$replace = ["🍎", "🍌", "🍊"];
$result = str_replace($search, $replace, $text);
echo $result . "\n"; // "🍎と🍌と🍊"
置換回数のカウント
$text = "The cat and the cat and the cat";
$count = 0;
$result = str_replace("cat", "dog", $text, $count);
echo $result . "\n"; // "The dog and the dog and the dog"
echo "置換回数: " . $count . "\n"; // "置換回数: 3"
大文字・小文字を区別しない置換 (str_ireplaceの使用)
$text = "Hello HELLO hello";
$result = str_ireplace("hello", "hi", $text);
echo $result . "\n"; // "hi hi hi"
配列内の要素の置換
$fruits = ["apple", "banana", "apple", "orange"];
$result = str_replace("apple", "grape", $fruits);
print_r($result); // ["grape", "banana", "grape", "orange"]
その他の使用例
// 使用例 1 : HTMLタグのエスケープ
function escapeHTML($text)
{
$search = ['<', '>', '"', "'", '&'];
$replace = ['<', '>', '"', ''', '&'];
return str_replace($search, $replace, $text);
}
$html = "<p>This is a 'test' & example</p>";
echo escapeHTML($html) . "\n";
// 使用例 2 : ファイル拡張子の変更
function changeFileExtension($filename, $newExt)
{
$info = pathinfo($filename);
return str_replace($info['extension'], $newExt, $filename);
}
$filename = "document.txt";
echo changeFileExtension($filename, "pdf") . "\n"; // "document.pdf"
// 使用例 3 : 電話番号のフォーマット
function formatPhoneNumber($phone)
{
$phone = str_replace(['-', ' ', '(', ')'], '', $phone);
return substr($phone, 0, 3) . '-' .
substr($phone, 3, 4) . '-' .
substr($phone, 7);
}
echo formatPhoneNumber("09012345678") . "\n"; // "090-1234-5678"
// 使用例 4 : 文字列のクリーニング
function cleanString($string)
{
$unwanted = ["\r", "\n", "\t", " "];
$wanted = ["", " ", " ", " "];
return trim(str_replace($unwanted, $wanted, $string));
}
$dirty = "This is a\n\t messy string";
echo cleanString($dirty) . "\n";
全角・半角
全角・半角が混ざった文字列を正確にカウントする場合、いくつかの方法が存在する。
必ず、エンコーディング (UTF-8等) を指定する必要があることに注意する。
また、全角・半角を区別してカウントする場合は、正規表現を使用することができる。
mb_strlen関数の使用
これは、簡便で高速な方法である。
$str = "1 あ イ";
$count1 = mb_strlen($str, 'UTF-8');
echo "mb_strlen(): " . $count1 . "\n"; // 結果: 5
preg_match_all関数を使用して文字単位でカウント
より複雑なパターンマッチングが必要な場合に使用する。
$str = "1 あ イ";
// preg_match_all関数の第3引数は、参照渡しのパラメータで、以下に示すような特徴がある。
// 関数の実行結果がこの変数に格納される
// 変数を事前に初期化する必要はない
// 関数内で自動的に配列として作成される
$count2 = preg_match_all('/./u', $str, $matches);
echo "preg_match_all(): " . $count2 . "\n"; // 結果: 5
配列に分解してカウント
$str = "1 あ イ";
$array = preg_split("//u", $str, -1, PREG_SPLIT_NO_EMPTY);
$count3 = count($array);
echo "preg_split(): " . $count3 . "\n"; // 結果: 5
mb_str_split関数の使用 (PHP 7.4以降)
文字列を配列に分解できるため、文字ごとの処理が必要な場合に便利である。
$str = "1 あ イ";
$array2 = mb_str_split($str);
$count4 = count($array2);
echo "mb_str_split(): " . $count4 . "\n"; // 結果: 5
空白を除外してカウント
$str = "1 あ イ";
$count_no_spaces = mb_strlen(str_replace(' ', '', $str), 'UTF-8');
echo "空白を除外: " . $count_no_spaces . "\n"; // 結果: 3
文字種別ごとにカウント
$str = "1 あ イ";
$zenkaku_count = preg_match_all('/[ぁ-んァ-ンー一-龠]/u', $str, $matches);
$hankaku_count = preg_match_all('/[\x{FF01}-\x{FF5E}]/u', $str, $matches);
$space_count = mb_substr_count($str, ' ');
echo "全角文字数: " . $zenkaku_count . "\n"; // 結果: 1
echo "半角カナ数: " . $hankaku_count . "\n"; // 結果: 1
echo "空白文字数: " . $space_count . "\n"; // 結果: 2
文字関数
英字の判別(ctype_alpha関数, ctype_alnum関数)
ctype_alpha
関数は、文字列に英字のみが含まれているかどうかを確認する。
boolean ctype_alpha(string text) 引数の文字列に英字だけが含まれているかどうかを確認します。 英字はa~z、A~Zである。 英字のみの文字列の場合はTRUE、英字以外が含まれている場合はFALSEを返す。 引数 text 調べる文字列 戻り値 文字列が全て英字である場合はTRUE、それ以外の場合はFALSEを返す。
ctype_alnum
関数は、英字と数字のみが含まれているかを確認する。
boolean ctype_alnum(string text) 引数の文字列に、英字と数字のみが含まれているかを確認する。 英字はa~z、A~Z、数字は0~9である。 英字と数字のみの文字列の場合はTRUE、英字と数字以外が含まれている場合はFALSEを返す。 引数 text 確認する文字列 戻り値 文字列が全て英字と数字である場合はTRUE、それ以外の場合はFALSEを返す。
<?php
$input_data = $_GET['text1'];
function dispKekka($str)
{
$kekka1 = ctype_alpha($str);
$kekka2 = ctype_alnum($str);
print('調べる文字列は'.$str.'です<br>');
if($kekka1 == TRUE)
{
print('文字列は英字だけが含まれています<br><br>');
}
else
{
if($kekka2 == TRUE)
{
print('文字列は英字及び数字だけが含まれています<br><br>');
}
else
{
print('文字列は英数字以外の文字が含まれています<br><br>');
}
}
}
$str = 'abcdef';
dispKekka($str);
$str = 'abc@def';
dispKekka($str);
$str = 'abc654def';
dispKekka($str);
?>
数字の判別(ctype_digit関数)
ctype_digit
関数は、文字列に数字のみが含まれているかを確認する。
boolean ctype_digit(string text) 文字列に数字だけが含まれているかを確認する。 数字のみの場合はTRUE、数字以外が含まれている場合はFALSEを返す。 引数 text 調べる文字列 戻り値 文字列が全て数字の場合はTRUE、それ以外の場合はFALSEを返す。
※注意
小数点等が含まれている場合もFALSE
となる。この関数では、全ての文字が0~9である必要がある。
引数に指定した値が、数値または数値として有効な文字列かどうかを判別する場合は、
数字または数値文字列の判別(is_numeric
関数)セクションを参照すること。
<?php
function dispKekka($str)
{
$bRet = ctype_digit($str);
print('調べる文字列は'.$str.'です<br>');
if($bRet)
{
print('文字列は数字だけが含まれています<br><br>');
}
else
{
print('文字列は数字以外の文字が含まれています<br><br>');
}
}
$str = '01234';
dispKekka($str);
$str = 'abc998';
dispKekka($str);
$str = '123.45';
dispKekka($str);
?>
大文字・小文字の判別(ctype_upper関数, ctype_lower関数)
ctype_upper
関数を使用して、文字列が全て大文字かどうかを確認する。
また、ctype_lower
関数を使用して、全て小文字かどうかを確認する。
boolean ctype_upper(string text) 引数の文字列が大文字かどうかを確認する。 引数 text 調べる文字列 戻り値 引数の全ての文字が大文字の場合はTRUE、それ以外の場合はFALSEを返す。 英字以外の文字が含まれている場合はFALSEとなる。 例えば、数字が含まれている場合はFALSEが返る。
boolean ctype_lower(string text) 引数の文字列が小文字かどうかを確認する。 引数 text 調べる文字列 戻り値 引数の全ての文字が小文字の場合はTRUE、それ以外の場合はFALSEを返す。
<?php
function dispKekka($str)
{
$kekka1 = ctype_upper($str);
$kekka2 = ctype_lower($str);
print('調べる文字列は'.$str.'です<br>');
if($kekka1 == TRUE)
{
print('文字列は大文字だけです<br><br>');
}
else
{
if($kekka2 == TRUE)
{
print('文字列は小文字だけです<br><br>');
}
else
{
print('文字列は大文字小文字が混合しています<br><br>');
}
}
}
$str = 'abc';
dispKekka($str);
$str = 'ABC';
dispKekka($str);
$str = 'abc89';
dispKekka($str);
$str = 'ABC89';
dispKekka($str);
?>
文字参照 (HTMLエンティティ) へ変換
htmlspecialchars
関数は、特殊文字 (<
や>
等) を文字参照 (HTMLエンティティ) に変換する。
htmlspecicalchars("$_POST["変数名"]", ENT_QUOTES);