【MySQL】数値に関する関数
こんにちは😊Kintarouです。
現在エンジニア転職を目指してプログラミング学習中です👨🎓
夢はフリーランスエンジニアになって働く人にとって働く事が楽しくなるシステムを作ること!
と、愛する妻と海外移住すること🗽
プログラミングや読んでいる本のことなど、ブログに書いていきます!
twitter : https://twitter.com/ryosuke_angry
今回参考にさせて頂いたサイト様🙇♂️ dotinstall.com
今回は数値に関する関数をいくつかまとめます。
COUNT()
まずは以下のデータ内のレコードの数を出力します。
CREATE TABLE tweets ( id INT NOT NULL AUTO_INCREMENT, message VARCHAR(140), likes INT, PRIMARY KEY (id) ); INSERT INTO tweets (message, likes) VALUES ('post-1', 12), ('post-2', 8), ('post-3', 11), ('post-4', 3), ('post-5', 8), ('post-6', 9), ('post-7', 4), ('post-8', 10), ('post-9', 31);
tweetsテーブル内のレコード数を取得します。
SELECT COUNT(id) FROM tweets;
※仮にカウントするカラム(今回の場合id)がNULLだった場合、カウントに含まれないので注意です。
SUM()
次にいいね数(likes)を足し合わせていきます。
SELECT SUM(likes) FROM tweets;
AVG()
次はいいね数(likes)の平均を出力します。
SELECT AVG(likes) FROM tweets;
MAX()
レコードの中で一番大きいいいね数(likes)を出力します。
SELECT MAX(likes) FROM tweets;
MIN()
レコードの中で一番小さいいいね数(likes)を出力します。
SELECT MIN(likes) FROM tweets;
以上、どなたかの参考になれば幸いです😊
【MySQL】IF・CASE文
こんにちは😊Kintarouです。
現在エンジニア転職を目指してプログラミング学習中です👨🎓
夢はフリーランスエンジニアになって働く人にとって働く事が楽しくなるシステムを作ること!
と、愛する妻と海外移住すること🗽
プログラミングや読んでいる本のことなど、ブログに書いていきます!
twitter : https://twitter.com/ryosuke_angry
今回参考にさせて頂いたサイト様🙇♂️ dotinstall.com
今日は簡単にMySQLのIF・CASE文をまとめます。
IF文
MySQLでIF文を使ってデータを抽出します。
今回のデータは以下です。
9つのツイートがあり、ツイート内容(message)、いいね数(likes)、位置情報(area)で構成されています。
CREATE TABLE tweets ( id INT NOT NULL AUTO_INCREMENT, message VARCHAR(140), likes INT, area VARCHAR(20), PRIMARY KEY (id) ); INSERT INTO tweets (message, likes, area) VALUES ('tweet-1', 12, 'Tokyo'), ('tweet-2', 8, 'Fukuoka'), ('tweet-3', 11, 'Tokyo'), ('tweet-4', 3, 'Osaka'), ('tweet-5', 8, 'Tokyo'), ('tweet-6', 9, 'Osaka'), ('tweet-7', 4, 'Tokyo'), ('tweet-8', 10, 'Osaka'), ('tweet-9', 31, 'Fukuoka');
この内容を、いいね数が10より多いかどうかで条件をつけてみます。
SELECT *, IF(likes > 10, 'A', 'B') AS rank FROM tweets;
likesが10より大ければ'A'、10以下であれば'B'というrankに分ける。という内容です。
CASE文
続いてCASE文です。
いいね数が10より大きければ'A'、10以下だが5より大きければ'B'、5以下なら'C'という風に分けます。
SELECT *, CASE WHEN likes > 10 THEN 'A' WHEN likes > 5 THEN 'B' ELSE 'C' END AS rank FROM tweets;
以上、どなたかの参考になれば幸いです😊
【MySQL】データ抽出(基本)
こんにちは😊Kintarouです。
現在エンジニア転職を目指してプログラミング学習中です👨🎓
夢はフリーランスエンジニアになって働く人にとって働く事が楽しくなるシステムを作ること!
と、愛する妻と海外移住すること🗽
プログラミングや読んでいる本のことなど、ブログに書いていきます!
twitter : https://twitter.com/ryosuke_angry
今回参考にさせて頂いたサイト様🙇♂️ dotinstall.com
MySQLでのデータ抽出方法です。簡単なものをいくつかまとめます。
全カラム出力
CREATE TABLE tweets ( id INT NOT NULL AUTO_INCREMENT, message VARCHAR(140), PRIMARY KEY (id) ); INSERT INTO tweets (message) VALUES ('Arigato'), ('arigatai'), ('Arigataya'), ('Nemutai'), ('Kanmuryo');
全カラム出力する場合は以下コマンドです。'*'がtweetsテーブルの全カラムを表しています。
SELECT * FROM tweets;
完全一致
以下のようにWHEREで条件式をつけます。
SELECT id,message FROM tweets WHERE message = 'Arigato';
完全不一致
条件式の!=は、等しく無い場合という事です。
SELECT id,message FROM tweets WHERE message != 'Arigato';
前方一致
LIKEと%を使い表現します。%は任意の文字列という解釈で大丈夫でしょう。
SELECT id,message FROM tweets WHERE message LIKE 'Ari%';
大文字小文字区別
LIKEにBINARYオプションをつける事で、大文字小文字を区別します。
id:2の'arigatai'が抽出から外れている事がわかります。
SELECT id,message FROM tweets WHERE message LIKE BINARY 'Ari%';
後方一致
%を前方につけ、任意の文字列の最後に'tai'がついているものを抽出します。
SELECT id,message FROM tweets WHERE message LIKE '%tai';
部分一致
部分一致の場合は%で囲みます。(下記の場合、'mu'が先頭や末尾にあった場合でも抽出します。)
SELECT id,message FROM tweets WHERE message LIKE '%mu%';
文字位置指定
'_'を使う事で特定文字位置を指定できます。例えば全てのmessageに'a'は入っていますが...
SELECT id,message FROM tweets WHERE message LIKE '%a%';
2文字目に'a'のあるmessageは'Kanmuryo'しかありません。
SELECT id,message FROM tweets WHERE message LIKE '_a%';
'_'は任意の文字列という解釈です。
仮に4文字目に'u'の入ったmessageを抽出したい場合は以下のようにします。
SELECT id,message FROM tweets WHERE message LIKE '___u%';
以上、どなたかの参考になれば幸いです😊
【MySQL】基本のデータ型と関数
こんにちは😊Kintarouです。
現在エンジニア転職を目指してプログラミング学習中です👨🎓
夢はフリーランスエンジニアになって働く人にとって働く事が楽しくなるシステムを作ること!
と、愛する妻と海外移住すること🗽
プログラミングや読んでいる本のことなど、ブログに書いていきます!
twitter : https://twitter.com/ryosuke_angry
今回参考にさせて頂いたサイト様🙇♂️ dotinstall.com
データ型
MySQLのデータ型について触れていきます。
下記以外にも型はありますが、主なものを載せていきます。
数値
データ型 | 値 |
---|---|
TINYINT | -128〜127 |
INT | -21億〜21億 |
BIGINT | −922京〜922京 |
TINYINT UNSIGNED | 0〜255 |
INT UNSIGNED | 0〜42億 |
BIGINT UNSIGNED | 0〜1844京 |
DECIMAL | 固定小数点 |
FLOAT | 浮動小数点 |
DOUBLE | 浮動小数点(高精度) |
数値の関数
数値関連の関数もまとめます。
関数名 | 処理 |
---|---|
FLOOR() | 端数切り捨て |
CEIL() | 端数切り上げ |
ROUND() | 四捨五入 |
文字列
データ型 | 値 |
---|---|
CHAR | 0〜255文字 |
VARCHAR | 0〜65535文字 |
TEXT | 65536文字以上 |
ENUM | 特定の文字列の内1つの値 |
SET | 特定の文字列の内複数の値 |
ENUMとSET補足
ENUMとSETに関しては具体例を出します。
CREATE TABLE posts ( id INT AUTO_INCREMENT, message VARCHAR(140), category ENUM('Gadget','Game','Buisiness'), PRIMARY KEY(id) ); INSERT INTO posts (message, category) VALUES ('post1', 'Gadget'), ('post2', 2), ('post3', 3); SELECT * FROM posts;
上記のようにあらかじめ文字列群を指定しておき、その中の1つという意味になります。
この際、'Game'や'Buisiness'のようにインデックス番号を指定する事もできます。
インデックス番号は0からではなく1からになっている点に注意です。
SETについても補足します。
DROP TABLE IF EXISTS posts; CREATE TABLE posts ( id INT AUTO_INCREMENT, message VARCHAR(140), category SET('Gadget','Game','Buisiness'), PRIMARY KEY(id) ); INSERT INTO posts (message, category) VALUES ('post1', 1), ('post2', 2), ('post3', 3), ('post4', 4), ('post5', 6), ('post6', 7); SELECT * FROM posts;
SETの場合インデックス番号が2の0乗(1)、2の1乗(2)、2の2乗(4)、となっていきます。
複数の値を入れられるのですが、インデックス番号1と2の場合は足した3を入れます。
例)post3 → 3(インデックス番号1(Gadget)、インデックス番号2(Game))
文字列の関数
関数名 | 処理 |
---|---|
SUBSTRING() | n番目以降を切り出す |
CONCAT() | 文字列を連結させる |
LENGTH() | 文字数を出力する |
CHAR_LENGTH() | 文字数を出力。漢字・ひらがな・カタカナ・マルチバイト文字も1文字に認識 |
真偽値
データ型 | 値 |
---|---|
BOOL | TRUE/FALSE |
TINYINT(1) | 1/0 |
日時
データ型 | 値 |
---|---|
DATE | 日付 |
TIME | 時間 |
DATETIME | 日時 |
日時の関数
関数名 | 処理 |
---|---|
NOW() | 現在の日時を返す |
YEAR() | 日付データから年を抜き出す |
MONTH() | 日付データから月を抜き出す |
DAY() | 日付データから日を抜き出す |
DATE_FORMAT() | 日付データを指定のフォーマットで出力 |
DATE_ADD | 指定の日付から○日後などを出力 |
DATEDIFF | 指定の日付2つの差を計算する |
以上、どなたかの参考になれば幸いです😊
【PHP】トークン機能を実装する
こんにちは😊Kintarouです。
現在エンジニア転職を目指してプログラミング学習中です👨🎓
夢はフリーランスエンジニアになって働く人にとって働く事が楽しくなるシステムを作ること!
と、愛する妻と海外移住すること🗽
プログラミングや読んでいる本のことなど、ブログに書いていきます!
twitter : https://twitter.com/ryosuke_angry
今回参考にさせて頂いたサイト様🙇♂️ dotinstall.com
CSRFの一例
まずはCSRFにてどのように攻撃されるかの一例を見ていきます。
前回記事でも用いた投稿機能のあるPHPファイルを使います。
■messages.txt
hello hi
■index.php
<?php require('../app/functions.php'); define('FILENAME', '../app/messages.txt'); if ($_SERVER['REQUEST_METHOD'] === 'POST') { $message = trim(filter_input(INPUT_POST, 'message')); $message = $message !== '' ? $message : '...'; $fp = fopen(FILENAME, 'a'); fwrite($fp, $message . "\n"); fclose($fp); header('Location: http://localhost:8080/result.php'); exit; } $messages = file(FILENAME, FILE_IGNORE_NEW_LINES); include('../app/_parts/_header.php'); ?> <ul> <?php foreach ($messages as $message): ?> <li><?= h($message); ?></li> <?php endforeach; ?> </ul> <form action="" method="post"> <input type="text" name="message"> <button>Post</button> </form>
■result.php
<?php require('../app/functions.php'); $message = trim(filter_input(INPUT_POST, 'message')); $message = $message !== '' ? $message : '...'; $filename = '../app/messages.txt'; $fp = fopen($filename, 'a'); fwrite($fp, $message . "\n"); fclose($fp); include('../app/_parts/_header.php'); ?> <p>Message added!</p> <p><a href="index.php">Go back</a></p>
ここにもし、以下のようなサイトがあった場合の挙動を見てみます。
仮にここで『今すぐ受け取る!』ボタンを押すと下記のような投稿がされてしまいます。
何故このような投稿がされてしまったのかを先ほどの怪しげなサイトのソースから確認してみます。
■winner.html
<!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>当選しました!</title> </head> <body> <h1>おめでとうございます!</h1> <!-- 指定したURLにPOSTで情報を送るフォームになっています。 --> <form action="http://localhost:8080/index.php" method="post"> <p>100万円が当たりました!下のボタンをクリックしてください!</p> <!-- hiddenとなって隠されていますが、messageという名前で犯行予告!!!!というデータが送られるようになっています。 --> <input type="hidden" name="message" value="犯行予告!!!!"> <button>今すぐ受け取る!</button> </form> </body> </html>
このように、ブラウザからページのソースで必要な情報がわかってしまうので別のサイトからでもデータを送る事ができ、反映されてしまします。
対策としては各種フレームワークを使うか、トークンを生成してそれが一致しているかを調べる必要があります。
今回はトークンを生成し、一致していた場合に処理を行う機能を実装していきます。
トークンの生成とチェック機能を実装する
トークン生成とチェック機能をfunctions.phpに記述していきます。
■functions.php
<?php function h($str) { return htmlspecialchars($str, ENT_QUOTES, 'UTF-8'); } function createToken() { #$_SESSION['token']がセットされていない場合にトークンを生成します。 if (!isset($_SESSION['token'])) { #random_bytes()関数で32文字のランダムな文字列を生成します。 #random_bytes()で生成されるのはバイナリ(2進数)なのでbin2hex()関数で16進数に変換します。 $_SESSION['token'] = bin2hex(random_bytes(32)); } } function validateToken() { if ( #$_SESSION['token']が空、もしくはPOSTで送られたtokenとは違う場合exit()で処理を終了させます。 empty($_SESSION['token']) || $_SESSION['token'] !== filter_input(INPUT_POST, 'token') ) { exit('Invalid post request'); } } #$_SESSION['token']でsessionを使うので、ここでsession_start()しておきます。 session_start();
トークン生成とチェック機能を組み込む
index.phpに組み込んでいきます。
■index.php
<?php #functions.phpを読み込みます。 require('../app/functions.php'); #早速トークンを生成します。 createToken(); define('FILENAME', '../app/messages.txt'); if ($_SERVER['REQUEST_METHOD'] === 'POST') { #POSTでデータが送信された際、下部フォームによって送られたトークンをチェックします。 #これでもしトークンが無い、トークンが誤っている(外部サイトからのPOST送信である)場合は処理が終了する。 validateToken(); $message = trim(filter_input(INPUT_POST, 'message')); $message = $message !== '' ? $message : '...'; $fp = fopen(FILENAME, 'a'); fwrite($fp, $message . "\n"); fclose($fp); header('Location: http://localhost:8080/result.php'); exit; } $messages = file(FILENAME, FILE_IGNORE_NEW_LINES); include('../app/_parts/_header.php'); ?> <ul> <?php foreach ($messages as $message): ?> <li><?= h($message); ?></li> <?php endforeach; ?> </ul> <form action="" method="post"> <input type="text" name="message"> <button>Post</button> <!-- このファイルの冒頭で生成したトークンをパラメータとして一緒に送ります。 --> <input type="hidden" name="token" value="<?= h($_SESSION['token']); ?>"> </form>
上記で更新したページのソースを確認すると、ランダムなトークンが生成されており、用意に攻撃する事が出来なくなっている事がわかります。
補足
トークンを実装することで今回のようなCSRFは防ぐ事が出来ますが、攻撃方法は多種多様に変化していくので、やはりフレームワークを使った開発が賢明です。
以上、どなたかの参考になれば幸いです😊
【PHP】POST送信による投稿機能の実装
こんにちは😊Kintarouです。
現在エンジニア転職を目指してプログラミング学習中です👨🎓
夢はフリーランスエンジニアになって働く人にとって働く事が楽しくなるシステムを作ること!
と、愛する妻と海外移住すること🗽
プログラミングや読んでいる本のことなど、ブログに書いていきます!
twitter : https://twitter.com/ryosuke_angry
今回参考にさせて頂いたサイト様🙇♂️ dotinstall.com
前回までの記事はGETメソッドによるデータの送信でしたが、今回はPOSTメソッドによるデータ送信を用いた投稿機能を実装してみます。
投稿機能の雛形を作る
投稿機能の雛形を作成します。
POST形式で送ったテキストデータを使い、messages.txtファイルを編集するという流れです。
ファイルを編集・操作する関数に関しては過去記事にまとめております。
■messages.txt
hello hi
2行分だけテキストを入れておきました。
まずはこのデータをindex.phpで表示します。
■index.php
<?php function h($str) { return htmlspecialchars($str, ENT_QUOTES, 'UTF-8'); } #messages.txtのテキスト内容を行毎に$messagesに配列形式で格納します。 #FILE_IGNORE_NEW_LINESにより\nは無視されています。 $filename = '../app/messages.txt'; $messages = file($filename, FILE_IGNORE_NEW_LINES); include('../app/_parts/_header.php'); ?> <!-- $messagesをforeach文で出力します。 --> <ul> <?php foreach ($messages as $message): ?> <li><?= h($message); ?></li> <?php endforeach; ?> </ul> <form action="result.php" method="post"> <!-- POST形式で新たなテキストデータを送れるようにしておきます。 --> <input type="text" name="message"> <button>Post</button> </form>
上記のようにmessages.txtのデータが表示されています。
新たにPOST形式で送ったテキストデータを使い、result.phpでmessages.txtに追記していきます。
■result.php
<?php #filter_input()関数でPOSTで送られたデータを$messageに代入します。 $message = trim(filter_input(INPUT_POST, 'message')); #記述が何もない場合は'...'を代入します。 $message = $message !== '' ? $message : '...'; #fwrite()関数で$messageを追記し、\nで改行しておきます。 $filename = '../app/messages.txt'; $fp = fopen($filename, 'a'); fwrite($fp, $message . "\n"); fclose($fp); include('../app/_parts/_header.php'); ?> <p>Message added!</p> <p><a href="index.php">Go back</a></p>
↓
↓
これで投稿機能が出来ました。
ただこの状態ではresult.phpにmessages.txt編集の記載がされているので、result.phpにURLから直接アクセスしたりページをリロードすると再投稿されるという事になってしまいます。
それを避けるには、index.phpで処理を行ってからresult.phpにリダイレクトする事によって解決できます。
URLの直アクセスやリロードに対応する
先ほどのファイル編集部分の記述をindex.phpに記載し、処理が出来たらresult.phpにリダイレクトするという形にします。
■index.php
<?php function h($str) { return htmlspecialchars($str, ENT_QUOTES, 'UTF-8'); } #下記2箇所で$filenameを使う機会があるのでdefine()で定数化します。 define('FILENAME', '../app/messages.txt'); #$_SERVERという特殊な変数でPOSTでアクセスされた場合に行う処理を記述出来ます。 #これにより、URLでの直アクセスに対応できます。 if ($_SERVER['REQUEST_METHOD'] === 'POST') { $message = trim(filter_input(INPUT_POST, 'message')); $message = $message !== '' ? $message : '...'; $fp = fopen(FILENAME, 'a'); fwrite($fp, $message . "\n"); fclose($fp); #messages.txtが編集出来たらresult.phpにリダイレクトします。 header('Location: http://localhost:8080/result.php'); exit; } $messages = file(FILENAME, FILE_IGNORE_NEW_LINES); include('../app/_parts/_header.php'); ?> <ul> <?php foreach ($messages as $message): ?> <li><?= h($message); ?></li> <?php endforeach; ?> </ul> <!-- 同じファイル内で処理をする場合はactionを空欄(もしくはactionの記述なし)で処理できます。 --> <form action="" method="post"> <input type="text" name="message"> <button>Post</button> </form>
ファイル編集部分がindex.phpに移った事により、result.phpの記述は簡単になります。
■result.php
<?php include('../app/_parts/_header.php'); ?> <p>Message added!</p> <p><a href="index.php">Go back</a></p>
これでURLでの直アクセスや、リロードに対応できます。
補足
この記事では別のサイトからアクセスされるCSRFに対応出来ていません。 CSRFに関しては過去記事の説明を再掲しておきます。
クロスサイトリクエストフォージェリ(CSRF)
ユーザーによる認証が完了したと考えられるWebアプリケーションのページに、悪意のあるコードやリンクを仕込む攻撃方法。
そのWebアプリケーションへのセッションがタイムアウトしていなければ、攻撃者は本来認証されていないはずのコマンドを実行できてしまいます。
GETとPOSTを適切に使い分けることと、上記のセキュリティトークンをリクエストに追加することで対策することができます。
ryosuke-toyama.hatenablog.com
以上、どなたかの参考になれば幸いです😊
【PHP】Sessionを活用し情報を保持する
こんにちは😊Kintarouです。
現在エンジニア転職を目指してプログラミング学習中です👨🎓
夢はフリーランスエンジニアになって働く人にとって働く事が楽しくなるシステムを作ること!
と、愛する妻と海外移住すること🗽
プログラミングや読んでいる本のことなど、ブログに書いていきます!
twitter : https://twitter.com/ryosuke_angry
今回参考にさせて頂いたサイト様🙇♂️ dotinstall.com
Sessionとは
Cookieのように情報を保持する事が出来ますが、Sessionはブラウザではなくサーバー側に保存します。
※Cookieについては過去記事にまとめてます。
ryosuke-toyama.hatenablog.com
そのため検証ツールで確認出来ず、編集や削除も出来ないため、機密性が高く重要な情報を取り扱うのに利用されます。
■CookieとSessionの主な違い
項目 | Cookie | Session |
---|---|---|
値の保存場所 | ブラウザ側 | サーバー側 |
サイズ | 制限あり | 制限なし |
保存できるもの | 文字列のみ | オブジェクトなどもOK |
安全性 | 低い | 高い |
扱うもの | 簡単な設定項目 | 認証情報など |
Sessionの仕組みを使い背景色情報を保持する
Sessionは、session_start()関数を使う事で利用を開始出来ます。
また、情報は$_SESSIONという変数に配列形式で保持されます。
ブラウザ側にはPHPSESSIDという特殊な形でCookieがセットされ、値にはブラウザとサーバー側の値を紐づける識別子が表示されます。(実際の値は見えないようになっています)
■functions.php
<?php #まずここでsession_start()を行います。 session_start(); function h ($str) { return htmlspecialchars($str, ENT_QUOTES, 'UTF-8'); }
■result.php
<?php require('../app/functions.php'); $colorFromGet = filter_input(INPUT_GET, 'color') ?? 'transparent'; #session_start()により$_SESSIONという特殊な変数が使えるようになったので、colorという名前で背景情報を保持します。 #サーバー側に情報を保持する仕組みのためsetcookie()する必要がありません。 $_SESSION['color'] = $colorFromGet; include('../app/_parts/_header.php'); ?> <p><?= h($colorFromGet); ?></p> <p><a href="index.php">Go Back</a></p>
■_header.php
<?php #_header.phpで$_SESSION['color']の背景色情報を$colorに代入します。 $color = $_SESSION['color'] ?? 'transparent'; ?> <!DOCTYPE html> <html lang="ja"> <head> <meta charset="utf-8"> <title>PHP Practice</title> </head> <body style="background-color: <?= h($color); ?>;">
上記のようにPHPSESSIDという特殊なCookieが生成され、Valueにはブラウザとサーバー側の値を紐づける識別子が表示されています。
このCookieが、サーバー側のColorという名前で保持されている背景色情報を引っ張ってきているイメージです。
Session情報の削除方法
Sessionの情報はunset()関数で削除します。
Session情報(color)を削除するためのreset.phpを作成してみます。
■index.php
<?php require('../app/functions.php'); include('../app/_parts/_header.php'); ?> <form action="result.php" method="get"> <label><input type="radio" name="color" value="orange">Orange</label> <label><input type="radio" name="color" value="pink">Pink</label> <label><input type="radio" name="color" value="gold">Gold</label> <button>Send</botton> <!-- reset.phpへのリンクを作成します。 --> <a href="reset.php">[reset]</a> </form>
上記のように[reset]リンクを作成し、reset.phpへジャンプします。
■reset.php
<?php require('../app/functions.php'); #unset()関数で$_SESSION['color']の値を削除します。 unset($_SESSION['color']); #header()関数は指定のURLにリダイレクトさせる事が出来ます。 header('Location: http://localhost:8080/index.php');
上記のように、$_SESSION['color']が削除されたため背景色が戻りました。
あくまで削除されるのはcolorの値であり、PHPSESSIDが削除されるわけではないので注意です。
header()関数注意点
本題ではないですがheader()関数が出てきたので注意点です。
①setcookie()同様、関数前にあらゆる出力の不可。
②LocationのLは必ず大文字にする。
③Location: の:(コロン)の後は半角スペースを必ず入れる。
④リダイレクトのURLは必ずhttpから記述する。
以上、どなたかの参考になれば幸いです😊