【PHP8.x】extract()関数の使い方
extract関数の使い方について、初心者にもわかりやすく解説します。
基本的な使い方
extract関数は、連想配列のキーを基に新しい変数を生成し、その値を配列の対応する要素の値で設定する関数です。この関数を使うと、配列の要素を個別の変数として、プログラム内で直接利用できるようになります。
例えば、$userData = ['firstName' => '太郎', 'age' => 30]; のような連想配列がある場合、extract($userData); を実行すると、$firstName という変数に '太郎' が、$age という変数に 30 が代入され、これらの変数をそれぞれ単独で扱えるようになります。これにより、配列の要素にアクセスする際の記述を簡潔にすることができます。
extract関数には、どのように変数を生成するかを制御するためのオプション(フラグ)を指定できます。例えば、既に存在する変数と同じ名前のキーが配列内にあった場合に、その変数を上書きするか、無視するか、または変数名の前に接頭辞を付けるかなどを細かく指定することが可能です。デフォルトでは、既存の変数を上書きします。
ただし、この関数は非常に便利である一方で、セキュリティ上の注意が非常に重要です。特に、$_GETや$_POSTのようなユーザーからの入力を受け取るスーパーグローバル変数を直接extract関数に渡すことは、深刻な脆弱性を引き起こす可能性があります。悪意のあるユーザーが意図しない変数を生成したり、プログラムの重要な設定や既存の変数を上書きしたりすることができてしまうためです。そのため、extract関数を使用する際は、渡す配列の内容が完全に信頼できるものであることを確認し、慎重に利用することが強く推奨されます。適切に使用すればコードの可読性や簡潔さを向上させることができますが、セキュリティリスクを十分に理解し、安全なプログラミングを心がける必要があります。
構文(syntax)
1<?php 2$user_data = [ 3 "name" => "Taro", 4 "age" => 25, 5 "city" => "Tokyo" 6]; 7 8// 配列のキーを、現在のスコープに変数として展開します 9extract($user_data); 10 11// 配列のキーと同じ名前の変数が利用可能になります 12echo $name; // "Taro" 13echo $age; // 25 14echo $city; // "Tokyo" 15?>
引数(parameters)
array &$array, int $flags = EXTR_OVERWRITE, string $prefix = ""
- array &$array: 変数に展開したい配列を指定します。配列のキーが変数名として使用されます。
- int $flags = EXTR_OVERWRITE: 配列のキーが既存の変数名と競合した場合の挙動を指定します。デフォルトは
EXTR_OVERWRITEで、既存の変数を上書きします。 - string $prefix = "": 配列のキーに付加するプレフィックスを指定します。
戻り値(return)
int
extract関数は、配列の各要素を個別の変数として展開した際に、新たに作成された変数の数を整数で返します。
サンプルコード
PHP extract関数で配列変数を展開する
1<?php 2 3/** 4 * 文字列から数値を抽出し、その結果をextract関数で変数としてスコープに展開するサンプル。 5 * extract関数自体は文字列から数値を直接抽出する機能はありません。 6 * 抽出された数値を格納した配列を、現在のスコープに変数としてインポートします。 7 * 8 * @param string $inputString 処理する入力文字列 9 * @return void 10 */ 11function extractNumbersFromStringAndToScope(string $inputString): void 12{ 13 echo "--- 入力文字列から数値を抽出 ---" . PHP_EOL; 14 echo "入力文字列: \"" . $inputString . "\"" . PHP_EOL; 15 16 $extractedData = []; 17 18 // 正規表現を使って文字列から「ID」に続く数値を抽出 19 // extract関数は文字列からの直接抽出は行いません。この部分は一般的なPHPの文字列処理です。 20 if (preg_match('/ID:\s*(\d+)/', $inputString, $matches)) { 21 $extractedData['itemId'] = (int)$matches[1]; 22 echo "抽出されたID: " . $extractedData['itemId'] . PHP_EOL; 23 } 24 25 // 正規表現を使って文字列から「Price」に続く数値を抽出 26 if (preg_match('/Price:\s*(\d+\.?\d*)/', $inputString, $matches)) { 27 $extractedData['itemPrice'] = (float)$matches[1]; 28 echo "抽出された価格: " . $extractedData['itemPrice'] . PHP_EOL; 29 } 30 31 echo PHP_EOL . "--- 抽出されたデータを配列として確認 ---" . PHP_EOL; 32 print_r($extractedData); 33 34 if (empty($extractedData)) { 35 echo "抽出できる数値が見つかりませんでした。" . PHP_EOL; 36 return; 37 } 38 39 echo PHP_EOL . "--- extract関数で配列を現在のスコープに展開 ---" . PHP_EOL; 40 // extract関数は、配列のキー(例: 'itemId')を変数名(例: $itemId)として、 41 // 配列の値(例: 101)をその変数の値として、現在のスコープにインポートします。 42 // EXTR_OVERWRITE は、同名の変数が既に存在する場合に上書きするデフォルトの挙動です。 43 $numberOfVariablesExtracted = extract($extractedData, EXTR_OVERWRITE); 44 45 echo "展開された変数の数: " . $numberOfVariablesExtracted . PHP_EOL; 46 47 echo PHP_EOL . "--- extract関数によって生成された変数を確認 ---" . PHP_EOL; 48 // extract関数によって、$itemId や $itemPrice といった変数がこのスコープで利用可能になります。 49 if (isset($itemId)) { 50 echo "変数 \$itemId: " . $itemId . " (型: " . gettype($itemId) . ")" . PHP_EOL; 51 } else { 52 echo "変数 \$itemId は展開されませんでした。" . PHP_EOL; 53 } 54 55 if (isset($itemPrice)) { 56 echo "変数 \$itemPrice: " . $itemPrice . " (型: " . gettype($itemPrice) . ")" . PHP_EOL; 57 } else { 58 echo "変数 \$itemPrice は展開されませんでした。" . PHP_EOL; 59 } 60 echo PHP_EOL; 61} 62 63// サンプル実行1: IDと価格を含む文字列 64extractNumbersFromStringAndToScope("Product details: ID: 101, Name: Laptop, Price: 1299.99 USD."); 65echo "---------------------------------------------------" . PHP_EOL; 66 67// サンプル実行2: IDのみ含む文字列 68extractNumbersFromStringAndToScope("Order number: 50023, Quantity: 5."); 69echo "---------------------------------------------------" . PHP_EOL; 70 71// サンプル実行3: 数値を含まない文字列 72extractNumbersFromStringAndToScope("No specific numbers here, just text."); 73
PHP 8.4のextract関数は、配列に格納されたデータを現在のプログラムのスコープに、新しい変数として展開する機能を提供します。このサンプルコードでは、まず入力文字列から正規表現を用いて「ID」や「Price」などの数値を抽出し、それらを$extractedDataという連想配列に整理しています。
その後、extract関数にこの$extractedData配列を渡すことで、配列のキー(例: 'itemId')が変数名(例: $itemId)となり、キーに対応する値がその変数の内容として、現在のスコープで直接利用できるようになります。
第一引数には展開したい配列を渡し、第二引数の$flagsには変数名が重複した場合の動作を指定します。サンプルではEXTR_OVERWRITEが使われており、既存の変数は上書きされます。第三引数$prefixを使うと、展開されるすべての変数名に指定した接頭辞を追加できます。関数は、展開された変数の総数を整数(int)で返します。
extract関数自体は文字列から数値を抽出する機能を持たず、あくまで既に用意された配列を、より使いやすい形で変数としてスコープに導入する役割を担います。
このサンプルコードは、まず正規表現で文字列から数値を抽出し、その結果を配列に格納しています。extract関数自体は文字列から数値を直接抽出する機能は持たず、用意された配列のキーを変数名、値をその変数の値として現在のスコープに展開する役割です。
extract関数の主な注意点は、配列のキー名がそのまま変数名となるため、既存の変数と名前が衝突し、意図せず値を上書きしてしまうリスクがあることです。特に、EXTR_OVERWRITEがデフォルトの挙動です。これにより、コードの予期せぬ動作や、外部からの悪意ある入力が直接変数として展開され、セキュリティ上の脆弱性につながる可能性もあります。そのため、extract関数の使用は慎重に行い、特にウェブアプリケーションなどで外部データを扱う場合は避けることが強く推奨されます。一般的には、配列の要素に直接アクセスするか、必要な変数を個別に代入する方が安全で可読性も高まります。
PHP extract関数で文字列から変数を展開する
1<?php 2 3/** 4 * URLクエリ文字列のようなフォーマットの文字列から情報を抽出し、 5 * それを変数として現在のスコープに展開する関数です。 6 * 7 * `extract`関数は配列のキーと値を現在のシンボルテーブルに変数をインポートするために使用されます。 8 * このサンプルでは、`parse_str`関数と組み合わせることで、 9 * キーワードである「文字列からの文字列抽出」の概念を具体的に示します。 10 * 具体的には、クエリ文字列から個々のパラメータ(キーと値のペア)を抽出し、 11 * それらを独立した変数として扱えるようにします。 12 * 13 * @param string $queryString 処理するクエリ文字列(例: "name=Alice&age=30&city=Tokyo") 14 */ 15function extractQueryStringVariables(string $queryString): void 16{ 17 // parse_str関数を使用して、クエリ文字列を連想配列に変換します。 18 // 例: "name=Alice&age=30" は ['name' => 'Alice', 'age' => '30'] となります。 19 // このステップで、元の文字列からキーと値のペアが「抽出」されます。 20 parse_str($queryString, $extractedData); 21 22 // extract関数を使用して、$extractedData配列のキーを変数名とし、 23 // 対応する値を現在のスコープに変数として展開します。 24 // 例: $extractedData['name'] の値が $name 変数として、 25 // $extractedData['age'] の値が $age 変数として利用可能になります。 26 // EXTR_OVERWRITE は、もし同じ名前の変数が既に存在した場合にその値を上書きするよう指示します。 27 extract($extractedData, EXTR_OVERWRITE); 28 29 // 抽出された変数にアクセスして結果を表示します。 30 // extractされた変数は、この関数のスコープ内で定義されます。 31 // null合体演算子 (??) を使用して、変数が定義されていない場合のデフォルト値を提供し、 32 // 未定義変数アクセスによるエラーを防ぎます。 33 echo "名前: " . ($name ?? '情報なし') . PHP_EOL; 34 echo "年齢: " . ($age ?? '情報なし') . PHP_EOL; 35 echo "都市: " . ($city ?? '情報なし') . PHP_EOL; // cityは存在する場合のみ表示 36 echo "--------------------" . PHP_EOL; 37} 38 39// --- 使用例 --- 40 41// 1. 標準的なクエリ文字列からの情報抽出 42echo "--- ユーザーデータ1 ---" . PHP_EOL; 43extractQueryStringVariables("name=Alice&age=25&city=Tokyo"); 44 45// 2. 一部の情報が欠けているクエリ文字列からの情報抽出 46// この場合、'age' と 'city' は定義されないため、「情報なし」と表示されます。 47echo "--- ユーザーデータ2 ---" . PHP_EOL; 48extractQueryStringVariables("name=Bob&occupation=Engineer"); 49 50// 3. 空のクエリ文字列からの情報抽出 51// 全ての変数が定義されないため、「情報なし」と表示されます。 52echo "--- 空のデータ ---" . PHP_EOL; 53extractQueryStringVariables("");
PHPのextract関数は、配列のキーを変数名とし、対応する値をその変数の値として現在のスコープに展開する機能を提供します。このサンプルコードでは、まずparse_str関数を使って「name=Alice&age=30」のようなURLクエリ文字列を['name' => 'Alice', 'age' => 30]という連想配列に変換しています。これにより、元の文字列から個々の情報が抽出されます。
次に、この連想配列をextract関数に渡すことで、$nameや$ageといった独立した変数を自動的に生成し、それぞれの値が代入されます。引数$arrayには展開したい連想配列を渡します。$flags引数には、変数名の衝突時の挙動などを制御する定数を指定でき、サンプルではEXTR_OVERWRITEを使用して、もし同じ名前の変数が既に存在した場合にその値を上書きするよう指示しています。$prefix引数を使うと、生成される変数名の前に特定の文字列を追加できますが、このサンプルでは使用していません。
extract関数の戻り値は、正常にインポートされた変数の数を示します。このようにextract関数を利用することで、配列に格納されたデータを直接変数として扱い、コードの可読性を向上させたり、動的に変数を生成したりすることが可能になります。サンプルでは、存在しない変数にはnull合体演算子でデフォルト値を提供することで、安全にアクセスしている点もポイントです。
extract関数は、配列のキーを変数名として現在のスコープに展開するため、既存の変数名と衝突し、意図しない上書きを引き起こす可能性があります。特に、ユーザーからの入力など信頼できないデータを直接extractで展開すると、セキュリティ上の脆弱性につながる危険性があるため、使用には十分な注意が必要です。また、どの変数がextractによって生成されたのかコードの可読性が低下し、デバッグを難しくする原因となることもあります。一般的には、配列から個別に値を取り出すか、オブジェクトとしてデータを扱う方法が、より安全で推奨されます。どうしてもextractを使用する場合は、影響範囲を限定した狭いスコープで、かつEXTR_PREFIX_ALLなどのフラグを用いて変数名を明確にするなど、意図しない挙動を防ぐための対策を検討してください。
PHP extract 関数で配列を連想配列変数に展開する
1<?php 2 3/** 4 * PHPのextract関数は、配列のキーを変数として現在のスコープにインポートします。 5 * この関数は、テンプレートエンジンなどで配列から複数の変数を一括で作成する際に便利ですが、 6 * 変数名の衝突を引き起こす可能性があるため、使用するフラグを理解することが重要です。 7 */ 8function demonstrateExtractUsage(): void 9{ 10 // 1. 配列を定義します。 11 $data = [ 12 'username' => 'Alice', 13 'age' => 30, 14 'city' => 'New York', 15 ]; 16 17 echo "--- extract() の基本的な使い方 (EXTR_OVERWRITE - デフォルト) ---\n"; 18 echo " 既存の変数がない場合、配列のキーがそのまま変数として展開されます。\n"; 19 20 // extractを実行し、配列のキーを変数として現在のスコープにインポートします。 21 // デフォルトのフラグは EXTR_OVERWRITE で、同名の既存変数があれば上書きします。 22 extract($data); 23 24 // インポートされた変数にアクセスします。 25 echo " ユーザー名: " . $username . "\n"; 26 echo " 年齢: " . $age . "\n"; 27 echo " 都市: " . $city . "\n\n"; 28 29 // 既存の変数を上書きする例を示します。 30 // 既に存在する変数 'username' と 'age' を定義します。 31 $username = "Bob"; 32 $age = 25; 33 $country = "Japan"; // extract対象外の変数も定義 34 35 echo "--- 既存変数を上書きする挙動 (EXTR_OVERWRITE) ---\n"; 36 echo " extract実行前の既存変数: \$username = " . $username . ", \$age = " . $age . ", \$country = " . $country . "\n"; 37 38 // $data配列の 'username' と 'age' が既存の変数を上書きします。 39 // $city は $data に存在するため、値が 'New York' で上書きされます。(元の値も同じ) 40 // $country は $data に存在しないため影響を受けません。 41 extract($data, EXTR_OVERWRITE); // EXTR_OVERWRITEはデフォルトのため省略可能ですが、明示的に指定しています。 42 43 echo " extract実行後の変数: \$username = " . $username . " (Aliceに上書き)\n"; 44 echo " extract実行後の変数: \$age = " . $age . " (30に上書き)\n"; 45 echo " extract実行後の変数: \$city = " . $city . " (New Yorkのまま)\n"; 46 echo " extract実行後の変数: \$country = " . $country . " (Japanのまま)\n\n"; 47 48 // 次のデモのために、作成された変数をクリアします。 49 unset($username, $age, $city, $country); 50 51 echo "--- 既存変数をスキップする (EXTR_SKIP) ---\n"; 52 // 既存の変数として 'username' を定義します。 53 $username = "Charlie"; 54 $occupation = "Developer"; // extract対象外の変数も定義 55 56 $data2 = [ 57 'username' => 'David', // 'username' は既存変数と衝突 58 'email' => 'david@example.com', 59 ]; 60 echo " extract実行前の既存変数: \$username = " . $username . ", \$occupation = " . $occupation . "\n"; 61 62 // EXTR_SKIPフラグを使用すると、配列のキーと同名の既存変数がある場合、 63 // その変数は上書きされず、配列の値はスキップされます。 64 extract($data2, EXTR_SKIP); 65 66 echo " extract実行後の変数: \$username = " . $username . " (Charlieのまま、Davidはスキップ)\n"; 67 echo " extract実行後の変数: \$email = " . $email . " (新しくインポートされた)\n"; 68 echo " extract実行後の変数: \$occupation = " . $occupation . " (Developerのまま、影響なし)\n\n"; 69 70 // 次のデモのために、作成された変数をクリアします。 71 unset($username, $email, $occupation); 72 73 echo "--- 全ての変数にプレフィックスを付ける (EXTR_PREFIX_ALL) ---\n"; 74 $productData = [ 75 'id' => 101, 76 'name' => 'Laptop', 77 'price' => 1200, 78 ]; 79 $prefix = "prod"; // 付与したいプレフィックスを定義します 80 81 // EXTR_PREFIX_ALLフラグを使用すると、すべてのインポートされる変数名に 82 // 指定したプレフィックスがアンダースコア (_) を介して付与されます。 83 // これにより、変数名の衝突を安全に回避できます。 84 extract($productData, EXTR_PREFIX_ALL, $prefix); 85 86 echo " 商品ID: " . $prod_id . "\n"; 87 echo " 商品名: " . $prod_name . "\n"; 88 echo " 商品価格: " . $prod_price . "\n\n"; 89 90 // 最後に、extract関数の戻り値を確認します。 91 // extract関数は、正常にインポートされた変数の数を返します。 92 $anotherData = ['key1' => 'value1', 'key2' => 'value2', 'key3' => 'value3']; 93 // 既存変数 'key1' を定義しておきます。 94 $key1 = "original_value"; 95 96 echo "--- extract() の戻り値の例 (EXTR_SKIP使用) ---\n"; 97 echo " extract実行前の \$key1: " . $key1 . "\n"; 98 $importedCount = extract($anotherData, EXTR_SKIP); 99 echo " extract実行後の \$key1: " . $key1 . "\n"; // スキップされるため 'original_value' のまま 100 echo " extract実行後の \$key2: " . $key2 . "\n"; // 新しくインポートされる 101 echo " インポートされた変数の数 (EXTR_SKIP使用時): " . $importedCount . " (key1はスキップされたため、key2とkey3の2つのみ)\n"; 102 103 // 次のデモのために、作成された変数をクリアします。 104 unset($key1, $key2, $key3); 105} 106 107// 関数を実行します。 108demonstrateExtractUsage(); 109 110?>
PHPのextract関数は、指定された連想配列のキーを現在のスコープの変数名として、その値を対応する変数に代入する機能を提供します。これは、テンプレートエンジンなどで、データベースから取得した連想配列のデータを個別の変数として手軽に扱いたい場合に特に便利です。
第一引数$arrayには、変数として展開したい連想配列を指定します。この引数は参照渡しとなります。第二引数$flagsは、現在のスコープに同名の変数が既に存在する場合の挙動を制御する非常に重要なオプションです。例えば、デフォルトのEXTR_OVERWRITEフラグでは既存変数を配列の値で上書きしますが、EXTR_SKIPフラグを使用すると既存変数は上書きされず、配列の値はスキップされます。また、EXTR_PREFIX_ALLフラグを指定すると、全てのインポートされる変数名に、第三引数$prefixで指定した文字列が接頭辞としてアンダースコアを介して付与されます。これにより、既存の変数との名前衝突を安全に回避できます。
extract関数の戻り値は整数値で、正常に現在のスコープにインポートされた(新しく作成されたか、上書きされた)変数の総数を返します。この関数はコードを簡潔にするメリットがある反面、予期せぬ変数名の衝突やセキュリティ上の脆弱性につながる可能性もあるため、使用する際はフラグの意味を十分に理解し、注意深く利用することが推奨されます。
extract関数は配列のキーを変数としてインポートしますが、変数名の衝突に特に注意が必要です。デフォルトのEXTR_OVERWRITEフラグでは既存の変数を上書きするため、意図しないデータの消失や変更が発生する可能性があります。これを避けるには、EXTR_SKIPフラグで既存変数をスキプするか、EXTR_PREFIX_ALLフラグとプレフィックス指定で安全に変数を作成してください。ユーザー入力など信頼できないデータにextractを直接使用すると、既存の重要な変数を上書きし、セキュリティリスクに繋がる恐れがありますので、安易な利用は避けるべきです。コードの可読性やデバッグのしやすさを考慮すると、配列のままアクセスする方が推奨される場合が多いです。本関数は正常にインポートされた変数の数を整数で返します。
PHPでZIPファイルを展開する
1<?php 2 3/** 4 * 指定されたZIPファイルを指定されたディレクトリに展開します。 5 * 6 * @param string $zipFilePath ZIPファイルのパス 7 * @param string $destinationPath 展開先のディレクトリパス 8 * @return bool 展開が成功した場合はtrue、失敗した場合はfalse 9 */ 10function extractZipFile(string $zipFilePath, string $destinationPath): bool 11{ 12 // ZipArchiveクラスのインスタンスを作成 13 $zip = new ZipArchive; 14 15 // ZIPファイルを開く 16 // open() メソッドは成功時に true (ZipArchive::ER_OK) を返し、失敗時に整数エラーコードを返します。 17 $openResult = $zip->open($zipFilePath); 18 19 if ($openResult === true) { 20 // 展開先ディレクトリが存在しない場合は作成を試みます。 21 // mkdir() の第三引数に true を指定すると、親ディレクトリも再帰的に作成されます。 22 // 0755 はディレクトリのパーミッション(読み書き実行の権限)です。 23 if (!is_dir($destinationPath) && !mkdir($destinationPath, 0755, true)) { 24 echo "エラー: 展開先ディレクトリ '{$destinationPath}' を作成できませんでした。\n"; 25 $zip->close(); 26 return false; 27 } 28 29 // ZIPファイルの内容を指定したディレクトリに展開します。 30 if ($zip->extractTo($destinationPath)) { 31 echo "成功: '{$zipFilePath}' を '{$destinationPath}' に展開しました。\n"; 32 $zip->close(); // ZIPファイルを閉じる 33 return true; 34 } else { 35 echo "エラー: '{$zipFilePath}' の展開に失敗しました。\n"; 36 $zip->close(); // ZIPファイルを閉じる 37 return false; 38 } 39 } else { 40 // open() が失敗した場合のエラーメッセージ。 41 // open() が返すエラーコードは ZipArchive::ER_XXX 定数に対応します。 42 echo "エラー: '{$zipFilePath}' を開けませんでした。エラーコード: {$openResult}\n"; 43 return false; 44 } 45} 46 47// --- 使用例 --- 48// 展開したいZIPファイルのパスを指定してください。 49// この例では、スクリプトと同じディレクトリにある 'example.zip' を想定しています。 50// 実際には、このパスを適切なZIPファイルのパスに置き換えてください。 51$zipFile = __DIR__ . '/example.zip'; 52 53// 展開先のディレクトリパスを指定してください。 54// このディレクトリが存在しない場合は自動的に作成されます。 55// この例では、スクリプトと同じディレクトリに 'extracted' フォルダを作成します。 56$extractDir = __DIR__ . '/extracted'; 57 58// 注意: このコードを実行する前に、`$zipFile` で指定したパスに 59// 実際にZIPファイルが存在することを確認してください。 60// (例: `file1.txt` や `folder/file2.txt` などを含む `example.zip` を作成して配置する) 61 62// ZIPファイルを展開する関数を呼び出し 63extractZipFile($zipFile, $extractDir); 64 65?>
このPHPコードは、ZipArchiveクラスを利用してZIPファイルを指定されたディレクトリに展開する一連の処理をextractZipFile関数として実装しています。この関数は、展開したいZIPファイルのパスを$zipFilePath引数として、展開先のディレクトリパスを$destinationPath引数として受け取ります。
関数内部では、まずZipArchiveのインスタンスを生成し、openメソッドで指定されたZIPファイルを開きます。このopenメソッドは、成功時にはtrueを、失敗時にはエラーコードを戻り値として返します。ファイルが正常に開けた場合、$destinationPathで指定された展開先ディレクトリが存在しない場合はmkdir関数によって自動的に作成されます。次に、extractToメソッドを呼び出し、ZIPファイルに含まれる全てのファイルを指定されたディレクトリに展開します。
展開が成功した場合はtrueを、失敗した場合はfalseを関数の戻り値として返します。また、処理の状況に応じてコンソールにメッセージを出力します。このコードは、ウェブアプリケーションでアップロードされたZIPファイルをサーバー側で処理したり、プログラムが必要とするリソースファイルを配置したりする際に役立ちます。
このコードはZIPファイルを指定の場所に展開するものです。まず、ZIPファイルのパスと展開先ディレクトリのパスが、実際に存在しアクセスできるか確認してください。展開先のディレクトリが自動作成される際のパーミッション(0755)は、サーバー環境のセキュリティ要件に合っているか確認が必要です。不適切なパーミッションは、セキュリティリスクや後の処理に影響を与える可能性があります。また、ファイルが開けない、または展開に失敗した場合は、エラーメッセージを参考に原因を特定してください。処理の途中でエラーが発生しても、開いたZIPファイルは必ず閉じられています($zip->close())。コードを実行する前に、example.zipのような展開対象のZIPファイルを必ず準備するようにしてください。