function setToken($formName) {
// トークンを生成
$csrf_token = bin2hex(random_bytes(32));
// $_SESSION['csrf_token']が配列であることを確認
if (!isset($_SESSION['csrf_token']) || !is_array($_SESSION['csrf_token'])) {
$_SESSION['csrf_token'] = array();
}
$_SESSION['csrf_token'][$formName] = $csrf_token;
return $csrf_token;
}
<input type="hidden" name="form_name" value="entry-form">
<input type="hidden" name="csrf_token" value="<?php echo h(setToken('entry-form')); ?>">
session_start();
if ($_SERVER['REQUEST_METHOD'] == 'POST') {
$formName = $_POST['form_name'];
if (!isset($_POST['csrf_token']) || $_POST['csrf_token'] !== $_SESSION['csrf_token'][$formName]) {
exit('不正なリクエスト');
}
unset($_SESSION['csrf_token'][$formName]);
unset($_POST['form_name']);
}
POST:維持
GET:上書き
残したいなら、input[type="hidden"] を使ってフォームデータにパラメータを加える。
<?php
// 元のデータ
$keys = ["apple", "banana", "cherry"];
$values = [100, 200, 300];
// 空の連想配列を初期化
$associativeArray = [];
// foreach文で配列を作成
foreach ($keys as $index => $key) {
$associativeArray[$key] = $values[$index];
}
// 結果を表示
print_r($associativeArray);
?>
三項演算子は、条件式 ? 式1 : 式2 という記述を行うことで使用できます。
Null合体演算子(??)は、!is_null($hoge) ? $hoge : $fuga と等価で
エルビス演算子(?:)は、$hoge ? $hoge : $fuga と等価です。
function deleteDirectory($dir){
$iterator = new RecursiveDirectoryIterator($dir, RecursiveDirectoryIterator::SKIP_DOTS);
$files = new RecursiveIteratorIterator($iterator, RecursiveIteratorIterator::CHILD_FIRST);
foreach ($files as $file) {
if ($file->isDir()) {
rmdir($file->getPathname());
} else {
unlink($file->getPathname());
}
}
rmdir($dir);
}
// ファイル名をサニタイズしてセキュリティを確保
$file = basename($file);
$filePath = './uploads/' . $file;
if (file_exists($filePath)) {
// ダウンロードを開始するためのヘッダーを設定
header('Content-Type: application/octet-stream');
header('Content-Disposition: attachment; filename="' . $file . '"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Content-Length: ' . filesize($filePath));
// 出力バッファをクリア
ob_clean();
flush();
// ファイルを読み込んで出力
readfile($filePath);
// ダウンロード後にファイルを削除
unlink($filePath);
exit;
} else {
echo 'ファイルが存在しません。';
}
$moto_x = (int)$moto_x;
または、四捨五入する。
$moto_x = round($moto_x);
$form_order = array('first', 'second', 'third'); // 順序を定義
$ordered_values = array();
foreach ($form_order as $key) {
if (isset($_POST[$key])) {
$ordered_values[] = $_POST[$key];
}
}
// コンマ区切りの文字列に変換
$csv_string = implode(',', $ordered_values);
// 結果を表示(または他の処理)
echo $csv_string;
<?php
$max_posts_page = 3;
$count_post = 30;
$page_get = $_GET['p'] ?? '1';
$page_end = $page_get * $max_posts_page;
$page_first = $page_end - $max_posts_page;
$max_pages = ceil($count_post / $max_posts_page);
$max_pages = ( $max_pages == 0 ) ? 1 : $max_pages;
$this_page = basename(__FILE__);
?>
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width">
<title>ページネーション</title>
<link rel="icon" href="favicon.svg" type="image/svg+xml">
<style>
.pagination {
margin-top: 2em;
text-align: center;
font-size: 12px;
}
.pagination a,
.pagination span {
display: inline-block;
margin: 4px 2px;
text-decoration: none;
border-radius: 4px;
width: 30px;
height: 30px;
padding: 7px 0;
box-sizing: border-box;
color: #000;
border: 2px solid #000;
font-weight: bold;
line-height: 1;
}
.pagination a:hover {
color: #000;
opacity: 0.7;
}
.pagination .page-current {
border: none;
background: transparent;
}
.prev-x, .next-x {
cursor: no-drop;
}
</style>
</head>
<body>
<div class="pagination">
<div class="nav-links">
<?php if ($page_get == "1"): ?>
<span id="prev-x" class="prev-x page-numbers">‹</span>
<?php else: ?>
<a id="prev" class="prev page-numbers" href="./<?php echo $this_page ; ?>?p=<?php echo $page_get - 1; ?>">‹</a>
<?php endif; ?>
<?php if ($page_get != "1"): ?>
<a id="first" class="first page-numbers" href="./<?php echo $this_page ; ?>?p=1">1</a>
<?php endif; ?>
<?php if ($page_get >= "5"): ?>
<span id="dots_left" class="page-numbers dots">…</span>
<?php endif; ?>
<?php for ($i = max(2, $page_get - 2); $i < $page_get; $i++): ?>
<a id="page-numbers<?php echo $i; ?>" class="page-numbers" href="./<?php echo $this_page ; ?>?p=<?php echo $i; ?>"><?php echo $i; ?></a>
<?php endfor; ?>
<span aria-current="page" class="page-numbers page-current"><?php echo $page_get; ?></span>
<?php for ($i = $page_get + 1; $i <= min($page_get + 2, $max_pages - 1); $i++): ?>
<a id="page-numbers<?php echo $i; ?>" class="page-numbers" href="./<?php echo $this_page ; ?>?p=<?php echo $i; ?>"><?php echo $i; ?></a>
<?php endfor; ?>
<?php if ($max_pages - $page_get >= "4"): ?>
<span id="dots_right" class="page-numbers dots">…</span>
<?php endif; ?>
<?php if ($page_get != $max_pages): ?>
<a id="last" class="last page-numbers" href="./<?php echo $this_page ; ?>?p=<?php echo $max_pages; ?>"><?php echo $max_pages; ?></a>
<?php endif; ?>
<?php if ($page_get == $max_pages): ?>
<span id="next-x" class="next-x page-numbers">›</span>
<?php else: ?>
<a id="next" class="next page-numbers" href="./<?php echo $this_page ; ?>?p=<?php echo $page_get + 1; ?>">›</a>
<?php endif; ?>
</div>
</div>
</body>
</html>
<?php
use PHPMailer\PHPMailer\PHPMailer;
use PHPMailer\PHPMailer\Exception;
use PHPMailer\PHPMailer\SMTP;
require 'path/to/PHPMailer/src/Exception.php';
require 'path/to/PHPMailer/src/PHPMailer.php';
require 'path/to/PHPMailer/src/SMTP.php';
function sendMail($to, $toname, $subject, $body) {
// 文字エンコードを指定
mb_language('uni');
mb_internal_encoding('UTF-8');
$mail = new PHPMailer(true);
try {
//Enable SMTP debugging
//SMTP::DEBUG_OFF = off (for production use)
//SMTP::DEBUG_CLIENT = client messages
//SMTP::DEBUG_SERVER = client and server messages
$mail->SMTPDebug = SMTP::DEBUG_SERVER;
$mail->isSMTP();
$mail->Host = SMTP_SERVER;
$mail->SMTPAuth = true;
$mail->Username = SMTP_USER;
$mail->Password = SMTP_PASS;
$mail->SMTPSecure = 'tls';
$mail->Port = SMTP_PORT;
$mail->CharSet = "utf-8";
$mail->setFrom(FROM_MAIL, SITE_NAME);
$mail->addAddress($to, $toname);
//$mail->addReplyTo('info@example.com', 'Information');
//$mail->addCC('cc@example.com');
//$mail->addBCC('bcc@example.com');
//Attachments
//$mail->addAttachment('/var/tmp/file.tar.gz');
//$mail->addAttachment('/tmp/image.jpg', 'new.jpg');
$mail->isHTML(true);
$mail->Subject = $subject;
$mail->Body = $body;
$mail->send();
echo 'Message has been sent';
} catch (Exception $e) {
echo "Message could not be sent. Mailer Error: {$mail->ErrorInfo}";
}
}
?>
Fatal error: Uncaught Error: Class "SMTP" not found
use PHPMailer\PHPMailer\SMTP;
SMTPプロトコルを使用してメールを送信することができ、メッセージの配信可能性が向上します。また、SMTPクラスを使用することで、エラーハンドリングやデバッグ機能も利用できるようになり、問題が発生した際の原因特定が容易になります。
SMTP の暗号化方式は 使用するポート番号とセットで決まるのが基本です。
$mail->SMTPSecure = PHPMailer::ENCRYPTION_STARTTLS;
$mail->Port = 587;
$mail->SMTPSecure = PHPMailer::ENCRYPTION_SMTPS;
$mail->Port = 465;
PHPMailerで外部のメールサーバー(SMTPサーバー)を使う場合、自分のサーバーにメール送信機能は一切なくても問題ありません。PHPMailerは「メールを送るプログラム」ではなく、
外部のSMTPサーバーへ接続してメール送信を依頼するクライアントです。
つまり、あなたのサーバーはただの「PHPが動く場所」であればよく、
メール送信の実務はすべて外部SMTPサーバーが担当します。あなたのサーバー側には sendmail も postfix も不要です。
但し、外向きSMTPがブロックされていることもあります。その場合、2525番ポートでSMTP送信が可能なサービスなどを検討する。
OpenSSL で SMTP サーバーに直接接続できるか確認する
openssl s_client -starttls smtp -connect smtp.example.com:587
openssl s_client -connect smtp.example.com:465
成功する場合
大量の証明書情報が表示される
最後に 250 STARTTLS や 220 などの応答が返る
失敗する場合
Connection timed out(ポートが塞がれている)
Connection refused(相手が拒否)
何も返らず固まる(アウトバウンド制限)