ゆう's Blog
<th>タグ

<th>タグを行ヘッダーとして使用することは、技術的には間違いではありません。実際、HTMLの仕様では、<th>タグは列ヘッダーだけでなく行ヘッダーを示すこともできるとされています。このように使用することで、表の内容がより分かりやすくなる場合もあります。

「example.com/username/hoge.php」を「example.com/share/hoge.php?user=username」にリダイレクト

複数のPHPファイルがある場合、汎用的なリライトルールを設定することで、複数のファイルを一括して処理することができます。

.htaccessファイルの作成/編集: サーバーのドキュメントルートまたは適切なディレクトリにある.htaccessファイルを作成または編集します。

汎用的なリライトルールの追加: .htaccessファイルに以下のリライトルールを追加します:

RewriteEngine On RewriteRule ^([a-zA-Z0-9_-]+)/([a-zA-Z0-9_-]+)\.php$ /share/$2.php?user=$1 [L,QSA]

tableタグ
caption
h-1h-2
d-1d-2
Caption
H_2H_3
R_2D_22D_32
R_3D_23D_33
配列を保存する

implodeを使った方法

メリット
シンプルで読みやすい:カンマ区切りの文字列として保存されるため、簡単に人間が読める形式になります。
検索性:文字列として保存されるため、特定の要素を簡単に検索したい場合に便利です。

デメリット
形式の制約:配列の要素が文字列であり、カンマを含まないことが前提です。もし要素にカンマが含まれていると、解析が困難になります。
情報の欠落:多次元配列やオブジェクトなど、単純な文字列としては表現できないデータ構造を扱う際に不向きです。

serializeを使った方法

メリット
柔軟性:多次元配列やオブジェクトなど、複雑なデータ構造もそのまま保存できます。
完全な保存:配列の情報をそのまま失わずに保存できるため、取り出した際に元の構造を保ったまま復元できます。

デメリット
読みやすさ:人間が直接読むのには向いていない形式です。デバッグや直接の確認が難しくなります。
互換性:シリアライズされたデータはPHP特有の形式であるため、他のプログラム言語やツールとの互換性がありません。

まとめ
シンプルな文字列として保存し、読みやすさや単純な検索性を重視するなら、implodeを使用する方法が適しています。
複雑なデータ構造をそのまま保存し、復元時に完全な形で取り出したい場合は、serializeを使用する方法が優れています。

ラジオボタンのチェックでフォームを送信する

<form id="myForm" method="post"> <input type="radio" name="option" value="1" id="option1" checked> <label for="option1">Option 1</label> <input type="radio" name="option" value="2" id="option2"> <label for="option2">Option 2</label> </form>

document.addEventListener('DOMContentLoaded', (event) => { const form = document.getElementById('myForm'); const radioButtons = form.querySelectorAll('input[type="radio"]'); radioButtons.forEach((radio) => { radio.addEventListener('change', () => { form.submit(); }); }); });

ページネーション

<?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">&lsaquo;</span> <?php else: ?> <a id="prev" class="prev page-numbers" href="./<?php echo $this_page ; ?>?p=<?php echo $page_get - 1; ?>">&lsaquo;</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">&rsaquo;</span> <?php else: ?> <a id="next" class="next page-numbers" href="./<?php echo $this_page ; ?>?p=<?php echo $page_get + 1; ?>">&rsaquo;</a> <?php endif; ?> </div> </div> </body> </html>

fetch API

<form id="myForm" method="post"> <div> <label for="pref">都道府県</label> <select id="pref" name="pref"> <option value="01">北海道</option> <option value="02" selected>青森県</option> <option value="03">岩手県</option> </select> </div> <div> <label for="comment">コメント</label> <textarea id="comment" name="comment" required></textarea> </div> <div> <button type="submit">登録</button> </div> </form>

document.getElementById('myForm').addEventListener('submit', function(event) { event.preventDefault(); // デフォルトのフォーム送信を防ぐ var pref = document.getElementById('pref').value; var comment = document.getElementById('comment').value; fetch('submit.php', { method: 'POST', headers: { 'Content-Type': 'application/x-www-form-urlencoded' }, body: 'pref=' + encodeURIComponent(pref) + '&comment=' + encodeURIComponent(comment) }) .then(response => response.text()) .then(data => { alert('データが正常に送信されました'); }) .catch(error => { console.error('エラーが発生しました:', error); }); });

submit.php

<?php $servername = "localhost"; $username = "your_username"; $password = "your_password"; $dbname = "your_database"; $conn = new mysqli($servername, $username, $password, $dbname); if ($conn->connect_error) { die("接続に失敗しました: " . $conn->connect_error); } $pref = $_POST['pref']; $comment = $_POST['comment']; $sql = "INSERT INTO your_table (pref, comment) VALUES ('$pref', '$comment')"; if ($conn->query($sql) === TRUE) { echo "新しいレコードが作成されました"; } else { echo "エラー: " . $sql . "<br>" . $conn->error; } $conn->close(); ?>

INSERT ... ON DUPLICATE KEY UPDATE構文

// データを挿入または更新するSQL文 $sql = "INSERT INTO your_table (id, column1, column2) VALUES (:id, :column1, :column2) ON DUPLICATE KEY UPDATE column1 = VALUES(column1), column2 = VALUES(column2)"; $stmt = $pdo->prepare($sql); // パラメータの設定 $stmt->bindParam(':id', $id); $stmt->bindParam(':column1', $column1); $stmt->bindParam(':column2', $column2);

主キー(またはユニークキー)に基づいて動作します。これは、重複するキーがある場合にUPDATEを実行するためです。したがって、この構文を使用する場合は、必ずしもIDである必要はありませんが、ユニークキーまたは主キーに基づく必要があります。

複数のカラムを組み合わせてユニークキーを作ることは可能ですし、それを使ってINSERT ... ON DUPLICATE KEY UPDATE構文を使用することも可能です。実際、複合ユニークキーを設定すれば、複数カラムの組み合わせに基づいてINSERTまたはUPDATEを行うことができます。

例えば、次のように複合ユニークキーを設定します:

CREATE TABLE your_table ( id INT AUTO_INCREMENT PRIMARY KEY, column1 VARCHAR(255), column2 VARCHAR(255), column3 VARCHAR(255), UNIQUE KEY unique_key (column1, column2) );

このようにテーブルを作成した場合、column1とcolumn2の組み合わせがユニークキーとして機能します。これに基づいてINSERT ... ON DUPLICATE KEY UPDATE構文を使用する例を以下に示します:

// データを挿入または更新するSQL文 $sql = "INSERT INTO your_table (column1, column2, column3) VALUES (:column1, :column2, :column3) ON DUPLICATE KEY UPDATE column3 = VALUES(column3)"; $stmt = $pdo->prepare($sql); // パラメータの設定 $stmt->bindParam(':column1', $column1); $stmt->bindParam(':column2', $column2); $stmt->bindParam(':column3', $column3);

この例では、column1とcolumn2の組み合わせがユニークであるため、重複するデータがある場合にはcolumn3が更新され、重複しない場合には新しいレコードが挿入されます。

この方法なら複数カラムのユニーク性を活かしてデータの挿入および更新ができます。


CREATE TABLE your_table ( id INT AUTO_INCREMENT PRIMARY KEY, column1 VARCHAR(255) NOT NULL, column2 VARCHAR(255) NOT NULL, column3 VARCHAR(255), UNIQUE KEY unique_key (column1, column2) );

PHPMailer

<?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クラスを使用することで、エラーハンドリングやデバッグ機能も利用できるようになり、問題が発生した際の原因特定が容易になります。

食宅便の定期便でポイントを使う。

やり方:
1回分スキップして、その日に新たにポイントを使って1回分の注文を入れる。

適当な日にち分をスキップする。

1回分の注文をする。

1回分の注文(通常便)でも定期便の価格,送料になっている。
※「amazon pay」でも支払える。そして、「amazon pay」は「Amazon ギフトカード」が使える。

配送希望日にスキップした日にちを指定する。
そして、ポイントを使う。