- 投稿日:2019-08-04T23:32:51+09:00
RubyのRailsをMySQLでHerokuにあげてみた
今までの麻雀アプリは一人でずっとやるだけだったので、
もう少しデータ的なのを集められるようになりたいなーと思って
ちょっと改良しました。https://rubymahjong.herokuapp.com/
みんなのあがり回数とあがりまでの平均ツモ数を表示できるようにしました!
◇開発言語
ruby 2.6.3
◇サーバーサイドフレームワーク
ruby on rails 5.2.3
◇フロントエンドフレームワーク
Vue.js
◇データベース
MySQL
◇開発OS
mac
◇IDE
vscode
◇ソース管理
GitHub
◇アプリケーションプラットフォーム
Heroku忘れないうちにRuby On Railsのインストール手順とかまとめておきます。
Ruby On Railsのインストール
まぁ、Railsのインストール手順とかは色々記事があるのでそれを見ればできます。
自分はRails Girls ガイドを見ながら環境を作りました。(Girlじゃないけど)基本的にはRails Girls ガイドの通りに作業を進めればいいんですが、
Homebrewのインストールがうまく行きませんでした。
brew doctor を実行してエラーがないか確認したところ11:05:46 Users $ brew doctor Please note that these warnings are just used to help the Homebrew maintainers with debugging if you file an issue. If everything you use Homebrew for is working fine: please don't worry or file an issue; just ignore this. Thanks! Warning: "config" scripts exist outside your system or Homebrew directories. `./configure` scripts often look for *-config scripts to determine if software packages are installed, and which additional flags to use when compiling and linking. Having additional scripts in your path can confuse software installed via Homebrew if the config script overrides a system or Homebrew-provided script of the same name. We found the following "config" scripts: /Library/Frameworks/Python.framework/Versions/3.7/bin/python3.7-config /Library/Frameworks/Python.framework/Versions/3.7/bin/python3.7m-config /Library/Frameworks/Python.framework/Versions/3.7/bin/python3-config 11:05:52 Users $と大量のWarningが…。
原因ですが、「-config」ファイルにPathが通っているとWarningが発生するみたいです。
envコマンドで環境設定確認すると、確かにPythonのPathが通ってますね。11:12:40 Users $ env | grep PATH PATH=/Users/itoutoshiya/.rbenv/shims:/Library/Frameworks/Python.framework/Versions/3.7/bin:/usr/local/bin:/usr/bin:/bin:/usr/sbin:/sbin以下のサイトを参考に、
PathからPythonを除外してbrewコマンドを実行するエイリアスを作成しました。
参考:https://www.task-notes.com/entry/20141223/1419324649alias brew="env PATH=${PATH/\/Library\/Frameworks\/Python.framework\/Versions\/3.7\/bin:/} brew"コンソールを再起動してbrew doctorを再実行。
11:22:47 ~ $ brew doctor Your system is ready to brew.これでHomebrewのインストールはうまくできました!
残りのソフトは、Rails Girls ガイドの通りに実装できました。
MySQLのインストール
MySQLのインストール手順も参考になる記事はたくさんありますね。
自分は以下のサイトが分かりやすかったので参考にさせてもらいました。
https://qiita.com/fuku_tech/items/a380ebb1fd156c14c25bbrew install mysqlrailsプロジェクト作成
必要なものは全部インストールできたので、早速
mysqlを利用するRailsプロジェクトを作成します。
といっても、さすがRails。コマンド一つだけですぐにできます。rails new ./ -d mysql適当なフォルダにて上記コマンドを実行すればOKです。
VScodeにてコンソールを表示し、上記コマンドを実行すれば必要なファイルが勝手に作成されます。config/database.ymlを確認すると、ちゃんとMySQLを使う設定になってますね!
んで、早速Railsの起動コマンド「rails server」を実行。
デフォルトだと地球儀の絵がTOPページに表示されるはず。
うーん失敗。ただ、以下のメッセージからするに、mysqlに接続できていない感じ。
Can't connect to local MySQL server through socket '/tmp/mysql.sock' (2)というか、そもそもsqlサーバーを起動していないので、そりゃDB接続できないよってエラー出ますよね。
ということで、以下コマンドを実行してsqlサーバーを起動。mysql.server startうん。sqlサーバーは起動できたみたいです。
じゃぁもう一度Railsを起動し画面を確認!
まぁ、エラーになるよね。今回のエラー原因は以下の通り。Unknown database 'project_development'project_developmentってデータベースがないよーってい言ってますね。
project_developmentは、config/database.ymlで設定している
データベースですね。
mySqlにログインしようとしてもproject_developmentはないからエラーになりますね。
まぁ、project_developmentを作ってないので当たり前ですね。なので、project_developmentを作ります。
ただ、これもRailsを利用して作成することができます。
以下コマンドを実行するだけ!rails db:createはい!できましたー。
じゃぁもう一度Railsを起動し画面を確認!地球の絵!
見慣れた画像が表示されました!
とりあえず、これで環境面は一通りできました!テーブル作成
今回は、上がりまでにかかった自摸の回数をテーブルに記録させていきたいと思います。
Railsのコマンドを実行すると、テーブルやそのテーブルにアクセスするための機能(プログラムファイル)
も自動でできます。rails generate scaffold WonCount name:string wonCount:integerですが、上記コマンドだけだと肝心のテーブル自身は作成されません。
マイグレーションを実行する必要があります。
と言っても難しいことは何もしません。
以下コマンドを実行するだけです。rails db:migrate参考:https://www.sejuku.net/blog/14229
ここまでくれば、後はあがりまでの自摸数をDBに登録するAPIを実装するだけです。
Herokuへのデプロイ
ローカル環境ではうまく出来たので、早速インターネットに公開したいと思います。
サーバーは、またHerokuを使います。便利ですね、PaaS。
参考:http://arfyasu.hatenablog.com/entry/2016/01/11/035101
https://devcenter.heroku.com/articles/rails4#logging-and-assetsrails_12factor
rails_12factorというのをHeroku上で利用できるように設定します。
rails_12factorは、Herokuでのログを見れるようにするgem(Rubyのライブラリ)です。
Gemfileに以下記述を追加するだけでOKです。group :production do gem 'rails_12factor' endProcfile作成
Procfileを作成し、Heroku上での起動コマンドを記述します。
以下記述だけでOK。web: bundle exec rails server -p $PORTHerokuにアップ
はい。ここまで出来たらHerokuにアップします。
HerokuGitにアップする方法もありますが、
自身のGitHubにアップしたプロジェクトを利用します。んで、プロジェクトアップロード後にWebサイトを確認。
はい。失敗〜。
Herokuのログを見ます。コマンドプロンプトから以下コマンドを実行〜。heroku logs --tail --app rubymahjong※「rubymahjong」は、Herokuにアップしたプロジェクト名です。
Mysql2::Error::ConnectionError (Can't connect to local MySQL server through socket '/var/run/mysqld/mysqld.sock' (2)):MySQLに接続出来なくてエラーになってますね。
HerokuにMySQLのDB作成
MySQLを利用するにはHerokuにクレジットカードの情報を登録する必要があります。
クレジットカードの登録だけなら無料です。(2019/08/04現在)クレジットカード登録後、コマンドプロンプトから以下コマンドを実行しMySQLが利用できるようにcleardbアドオンをインストールします。
参考:https://www.yuta-u.com/programing/rails/heroku-mysql-2heroku addons:create cleardb:ignite --app rubymahjongHeroku上の「Overview」を見ると、MySQLがアドオンされたことが分かりますね。
以下コマンドを実行してコンフィグを確認しても、MySQLが追加されたことが分かります。
heroku config --app rubymahjongCLEARDB_DATABASE_URLに、デプロイ用のDB接続情報が記載されています。
CLEARDB_DATABASE_URL: mysql://bfc76098d1b006:90049602@us-cdbr-iron-east-02.cleardb.net/heroku_c287fee3253ccb2?reconnect=trueこの情報をDATABASE_URLとして設定します。
ただし、Railsのgemでインストールしているのがmysql2のため、
mysqlではなくmysql2に変更して設定します。heroku config:set DATABASE_URL=mysql2://bfc76098d1b006:90049602@us-cdbr-iron-east-02.cleardb.net/heroku_c287fee3253ccb2?reconnect=true --app rubymahjong変更後、またコンフィグを確認してみます。
【変更後】
heroku config --app rubymahjong
DATABASE_URLが追加されてますね!ActiveRecord::StatementInvalid (Mysql2::Error: Table 'heroku_c287fee3253ccb2.won_counts' doesn't exist: SHOW FULL FIELDS FROM `won_counts`):won_countsテーブルがなくてエラーになってますね。
テーブル作成はマイグレーションですね。以下コマンドを実行!
heroku run rails db:migrate --app rubymahjongなんか出来てる感じですね!
早速ブラウザから画面を確認してみます。
できました!
きちんとあがり回数をDBに登録し、その結果を出力出来てます!Herokuって便利ですねー。
Rails+MySQLってかなりのWebサービスで利用されてそうで、
その環境が簡単に作れると色々なことが出来て夢が広がりますね!
今回のプログラムは以下GitHubにあげてます。
https://github.com/kph7m/rubymahjong
- 投稿日:2019-08-04T23:14:32+09:00
RDSスナップショットを、テスト用にマスクする、CodeBuildとdbtestdataで
本番RDSスナップショットをそのままテスト用に使うわけにいかない。個人情報とか業務上の機密とか。マスクします。みなさんどうやってるんですかね。
全体像
こんな流れで作ります。
- create RDS Instance
- Data masking
- RDS create snapshot
- RDS instance shutdown
この記事では 2. のところを扱います。ほかは手作業。そのうちawscliとCodeBuildで自動化する。
マスク設定ファイルをつくるのに必要な情報を用意する
- information_schema.tables, columnsを漁る
- テーブルそのものの要否をふりわける
- 必要なテーブルについて、マスクすべきカラムを選別する
- カラムごとに、どんなデータパターンでマスクするか決める
マスク設定ファイルをつくる
マスクツールは dbtestdata を使います。dbtestdata用のマスク設定ファイルを作ります。dbtestdataがMySQLしか対応してないので、MySQLかAurora(MySQL互換)にしか使えないのがツラい。
DBマイグレーションを管理しているgitリポジトリに、
dbmask/dbtestdata.update.${TABLE_NAME}.confと作っていくことにします。テーブルごとに1ファイル作ります。このように。package sample; use strict; use warnings; use data::VariableDataGenerator; use sql::VariableSQLGenerator; use utf8; return { name => __PACKAGE__, update => { users => { primary => "id", clazz => { name => RANDOM_JA_NAME_KAN, email => RANDOM_EMAIL, address => RANDOM_JA_PREF, tel => RANDOM_JA_TEL, } } } };カラムごとに、どのようにマスクするかをチクチク書いていきます。マスク不要なカラムは記載不要です。なにがどうなってるのかは、 GitHub - dino-tools/dbtestdata: database testdata generator を漁ってください。
DBマイグレのgitリポジトリに入れておきたいのは、DBマイグレによるスキーマ変更と同調して、マスク設定もアップデートしていきたいからです。テーブルごとにしたいのは、gitでコンフリクトを少なくしたいのと、CodeBuildで並列実行させたいからです。
RDSインスタンスを立てる
RDSスナップショットから、RDSインスタンスを立てます。本番環境とは別のVPCにするのが事故防止のためにも良いでしょう。手作業でチクチク立てます。CodeBuildから接続できるよう、RDSインスタンス側のセキュリティグループを調整しておきます。
CodeBuildビルドプロジェクトをつくる
buildspec.ymlはこんな。 envの部分は、よしなに置き換えて使ってください。RDSに接続するので、このCodeBuildはVPC内で動かします。Dockerイメージは、惰性で ansible/ausible-runner を利用してます。wgetとか要るのか、、、なんか要らない気がしてきた。
version: 0.2 env: variables: RDS_ENDPOINT: "hoge" RDS_USER: "hoge" CONF_FILE: "hoge" parameter-store: RDS_PASSWD: /CodeBuild/RDS_PASSWD phases: install: commands: - env | sort - yum install -y -q wget which unzip jq perl-DBI perl-DBD-MySQ mariadb-server - git clone https://github.com/dino-tools/dbtestdata.git /usr/local/dbtestdata build: commands: - | cd /usr/local/dbtestdata echo ${RDS_PASSWD} \ | perl dbtestdata.pl update \ --hostname=${RDS_ENDPOINT} \ --database=production_asp \ --username=${RDS_USER} \ --password \ --conf=${CODEBUILD_SRC_DIR}/dbmask/${CONF_FILE}ちなみにCodeBuildは実行時間が8時間までの制限があるので、クソデカいテーブルには制限時間オーバーで駄目になります。ラッキーなことに、8時間以内に終わるテーブルだけだったので、今後そのうち考えます。たぶんFargateとかでやると思います。いやどうだろう、わからない。
マスクする
こちらもCodeBuildにやらせます。テーブル数が多い場合は、同時実行数を絞ったり、RDBのグレードを上げたりの工夫が必要になるかと思います。両方で同じバージョンを利用するよう、
--source-version "${CODEBUILD_SOURCE_VERSION}"を付けてます。phases: install: commands: - env | sort - yum install -y -q wget which unzip jq - pip install --upgrade --quiet pip - pip install --quiet awscli - aws --version build: commands: - | cd ${CODEBUILD_SRC_DIR}/dbmask; ls dbtestdata.update.*.conf \ | sort \ | while read CONF_FILE; do aws codebuild start-build \ --source-version "${CODEBUILD_SOURCE_VERSION}" \ --project-name dbtestdata-runner \ --environment-variables-override name="CONF_FILE",value="${CONF_FILE}",type="PLAINTEXT" done要らんテーブルは空にする
テストの要件などから、空でいいテーブルが多々あります。dbtestdataにもdeleteする機能はありますが使いません。外部キー制約の on delete が動いてしまったりで厄介だったので、mysqlコマンドでtruncateすることにしました。
--init-command="SET SESSION FOREIGN_KEY_CHECKS=0;"を付けたかった。${CODEBUILD_SRC_DIR}/dbmask/delete.confは、1行1テーブル名の、ただのテキストファイルです。version: 0.2 phases: install: commands: - env | sort - yum install -y -q wget which unzip jq perl-DBI perl-DBD-MySQ mariadb-server build: commands: - | cat ${CODEBUILD_SRC_DIR}/dbmask/dbtestdata.delete.conf \ | sort -u \ | while read TABLE_NAME; do mysql -u ${RDS_USER} -p${RDS_PASS} -h ${RDS_HOST} production_asp \ --init-command="SET SESSION FOREIGN_KEY_CHECKS=0;" \ -e "truncate table ${TABLE_NAME};" doneRDSスナップショットを作って、開発アカウントに共有し、RDSを立てる
他のアカウントに共有するにはこのように。
aws rds modify-db-snapshot-attribute \ --db-snapshot-identifier masked-snapshot \ --attribute-name restore \ --values-to-add '["xxxxxxxxxxxxxxxxx"]'DBマイグレーションに並走する
ほっとくとマスク定義が古くなっていきます。テーブルの追加削除もあります。カラムの追加削除もあります。アプリケーションチームと、DBマイグレの都度、マスク定義ファイルのアップデートもしていくよう、ルール作りを忘れずに。
- 投稿日:2019-08-04T23:04:08+09:00
Railsで本番サバーからDemoサバーにデータをコピーする
Railsで本番サバーからDemoサバーにデータをコピーする (rake task)
今Railsプロジェクトを開発している、その時は本番サバーはドンドン新しいデータが登録している。そして同じデータをテストしたい時難しいと思います。したのコート使ってTerminalからデータをコピーができる。
# lib/tasks/db_pull.rake namespace :db do desc 'Pull production db to development' task :pull => [:dump, :restore] task :dump do dumpfile = "#{Rails.root}/tmp/latest.dump" production = Rails.application.config.database_configuration['production'] puts 'mysqldump on production database...' system "ssh user@server.tld 'mysqldump -u #{production['username']} --password=#{production['password']} -h #{production['host']} --add-drop-table --skip-lock-tables --verbose #{production['database']}' > #{dumpfile}" puts 'Done!' end task :restore do dev = Rails.application.config.database_configuration['development'] abort 'Live db is not mysql' unless dev['adapter'] =~ /mysql/ abort 'Missing live db config' if dev.blank? dumpfile = "#{Rails.root}/tmp/latest.dump" puts 'importing production database to development database...' system "mysql -h #{dev['host']} -u root #{dev['database']} < #{dumpfile}" puts 'Done!' end endrake db:pullReference: https://martinschurig.com/posts/2015/02/pulling-production-database-to-local-machine-rails-task/
- 投稿日:2019-08-04T04:43:59+09:00
PHP For Beginnersチュートリアル その7 基本的なコンタクトフォームの実装
このシリーズの目的
体系的なwebコーディングの訓練ができるようになるために、PHPの初学のきっかけかつ、PHPでログインフォームやフォームを実装することができるようになるために
上記のチュートリアルを進めているのでその備忘録。
内容
今回のチュートリアル
PHP Tutorial: Create Contact Form & Send an Email With Attachment Using PHPMailer
このチュートリアルでやること
・簡単なコンタクトフォームの作り方を覚える
・フォームに書かれた内容と添付ファイルをPHPを使ってEメールで送信する成果物
index.php<?php $msg = ""; use PHPMailer\PHPMailer\PHPMailer; use PHPMailer\PHPMailer\Exception; if (isset($_POST['submit'])) { mb_language("japanese"); mb_internal_encoding("UTF-8"); require 'vendor/autoload.php'; require 'Mairtrap-config.php'; // メール送信を行うための関数 function sendemail($to,$from,$fromName,$body,$attachment) { $mail = new PHPMailer(); // Server $mail->SMTPDebug = 0; //本番では0とかにする。 $mail->isSMTP(); $mail->SMTPAuth = true; $mail->Host = MAIL_HOST; $mail->Username = MAIL_USERNAME; $mail->Password = MAIL_PASSWORD; $mail->SMTPSecure = MAIL_ENCRPT; $mail->Port = SMTP_PORT; // Recipients $mail->setFrom($from,$fromName); $mail->addAddress($to); $mail->addAttachment($attachment); // Content $mail->FromName = mb_encode_mimeheader("$fromName", "ISO-2022-JP", "UTF-8"); $mail->Subject = mb_encode_mimeheader("Contact Form test", "ISO-2022-JP", "UTF-8"); $mail->Body = mb_convert_encoding("$body","JIS","UTF-8"); $mail->CharSet = 'ISO-2022-JP'; $mail->Encoding = "7bit"; // Select HTML or NOT $mail->isHTML(false); return $mail->send(); } //ここまで $name= $_POST['username']; $email= $_POST['email']; $body = $_POST['body']; $file = "attachment/". basename($_FILES['attachment']['name']); //デバック用のコード、本番時はオフ // echo "<pre>"; // print_r($_FILES); if (move_uploaded_file($_FILES['attachment']['tmp_name'],$file)) { if(sendemail("test@to.example.com",$email,$name,$body,$file)) $msg = "Email sent"; else $msg = "Error"; } else $msg = "Please check your attachment!"; } ?> <!DOCTYPE html> <html> <head> <title>PHP contactform tutorial</title> <link rel="stylesheet" href="css/sample1.css"> </head> <body> <div class="form"> <img src="img/icon.png" alt="アイコン"> <form action="index.php" method="post" enctype="multipart/form-data"> <input type="text" name="username" placeholder="Name" required><br> <input type="text" name="email" placeholder="Email" required><br> <textarea name="body" placeholder="what`s up?" required></textarea><br> <input type="file" name="attachment" required><br> <input type="submit" name="submit" value="Send Email"><br> </form> </div> <br><br> <?php echo $msg; ?> </body> </html>sample1.cssinput,textarea { width:250px; height:27px; margin-bottom:10px; } textarea { height: 100px; resize:vertical; } body { text-align: center; margin-top: 150px; } img{ height: 100px; width:200px; }添付ファイルを送れるようなフォームを作る手順
1.formタグにおいてmethod属性をPOSTにする
2.enctype属性を追加し内容をmutipart/form-dataにする。
3.type属性がfileのinputタグを書く
2,3が肝。
今回のコードの注釈
$_FILESについて$file = "attachment/". basename($_FILES['attachment']['name']); /*$_FILESはHTTPのPOSTメソッドでアップロードされたファイルの値を取得するファイルアップロード変数。平たく言うと、クライアントからサーバーへファイルをアップロードするために必要な変数であり、送信されてきたデータのうち、type属性がfileであるinputタグの部分のデータが連想配列でこの変数に格納されることになる。 格納されるデータは以下の通りであり、必ず最初にinputタグで指定したname属性の値を引数に設定していることがわかる。 $_FILES['inputで指定したname']['name'] ファイル名 $_FILES['inputで指定したname']['type'] ファイルのMIMEタイプ $_FILES['inputで指定したname']['tmp_name'] サーバー上で一時的に保存されるテンポラリファイル名 $_FILES['inputで指定したname']['error'] アップロード時のエラーコード $_FILES['inputで指定したname']['size'] ファイルサイズ(バイト単位) よって今回の場合、<input type="file" name="attachment" required>と指定しているので、例えばbg.jpgというファイルをアップロードすると各データとキーと値は以下のようになる。 Array ( [attachment] => Array ( [name] => bg.png [type] => image/png [tmp_name] => C:\xampp\tmp\phpEE16.tmp [error] => 0 [size] => 20918 ) ) また、basenameはファイルあるいはディレクトリへのパスを含む文字列を受け取って、最後にある名前の部分を返す関数で要はファイル名やディレクト名を取得するための関数である。 つまり、$file = "attachment/". basename($_FILES['attachment']['name']);というのはattachmentフォルダにある$_FILESでアップロードされてきたファイルの名前ということになり、次で触れるmove_upload_file関数を使うために必要なパスを書いていると思えばいい。*/ ?>move_upload_fileについてif (move_uploaded_file($_FILES['attachment']['tmp_name'],$file)) { if(sendemail("test@to.example.com",$email,$name,$body,$file)) $msg = "Email sent"; else $msg = "Error"; } else $msg = "Please check your attachment!"; } /*move_upload_fileはクライアントからのリクエストでアップロードされたファイルの保存場所を変更する際に使用する関数である。 そもそもファイルアップロードの仕組みから説明すると、アップロードされたファイルは任意の一時フォルダに保存される。先に出したキーと値でいうと [tmp_name] => C:\xampp\tmp\phpEE16.tmp この部分を見ればいい、tmpというフォルダに仮に保存されているのがわかる。 仮に保存されているということは、一定時間で消えるということなのでそうならないために。これを別の専用のフォルダに移すための関数がmove_upload_file関数ということである。 内容は簡単、第1引数に移動前のパス、第2引数に移動後のパスを指定してやればいい。 今回の場合は$_FILESにおいてサーバーに一時的に保存されるファイル名の引数の設定の仕方は上に書いてあるように、$_FILES['inputで指定したname']['tmp_name']であるからそれを第1引数に設定し、第2引数には先程設定した$fileを指定する。 つまり、先程の$fileはアップロードされたファイルの保存場所を指定したということが逆説的にわかる。 あとは簡単な話で、functionでメール送信の為の一連の処理はまとめてあるので、関数作成の際に設定した引数を入れてif文で条件分岐してエラーメッセージ等を適宜出すようにすればいい。 ちなみに今回指定した引数は左から順に 送り先のアドレス、inputタグのname属性がemail箇所から送信されてきた値(フォームに入力されたメールアドレス、通常の場合は補足の項目にあるように送り主のアドレス)、inputタグのname属性がusernameの箇所から送信されてきた値(フォームに入力された名前、通常の場合は送り主の名前)、メール本文、添付ファイル(ない場合は書かなくていい)となっている。 */補足
1.複数のメールアドレスにメールを送信するためには?
成果物の下記の部分においてsendemailで別のアドレスと引数を指定してやればいい。
if (move_uploaded_file($_FILES['attachment']['tmp_name'],$file)) { if(sendemail("test@to.example.com",$email,$name,$body,$file)) $msg = "Email sent"; //中略 //これを例えば以下のようにする if (move_uploaded_file($_FILES['attachment']['tmp_name'],$file)) { if(sendemail("test@to.example.com",$email,$name,$body,$file)) $msg = "Email sent"; sendemail("test@example.com","post@mail.com","website","hey!"); //中略こうすると、"test@to.example.com"と"test@example.com"へ送られるメールの内容を変えつつ同時に送信することができる。
今回のようなメールフォームには必要ないが覚えておこう。2.日本語の部分が文字化けする(件名、送信者名、本文等)
成果物のように以下のコードを必ず記載する。
チュートリアルは英語の教材でかつ、英語圏の人たちを対象に想定して作られているので特に言及されていないが、チュートリアルのまま日本語を本文等に使うと必ず文字化けするので忘れないこと。設定するコードmb_language("japanese"); mb_internal_encoding("UTF-8"); $mail->FromName = mb_encode_mimeheader("$fromName", "ISO-2022-JP", "UTF-8"); $mail->Subject = mb_encode_mimeheader("Contact Form test", "ISO-2022-JP", "UTF-8"); $mail->Body = mb_convert_encoding("$body","JIS","UTF-8"); $mail->CharSet = 'ISO-2022-JP'; $mail->Encoding = "7bit";参考
PHPでmove_uploaded_file関数を使う方法【初心者向け】
PHPでファイル名や拡張子,ディレクトリ名を取得する方法
PHP $_FILES(ファイル変数)のすべて!【初心者向け基本】
PHPで日本語メールを送信する
- 投稿日:2019-08-04T00:39:38+09:00
php mysql でsql injectionに対応したhashログイン処理を実装した例
php mysql でsql injectionに対応したログイン処理を実装した例
phpとmysqlでセッションログイン処理を実装するときにとかそういうのを作るのが面倒だったので、exampleを残します。。
依存パッケージのinstall
composer require josegonzalez/dotenvログイン処理をするとき
// sign up $userInfo = $login->signup("username","xxx@example.com", "12345678"); //login $userInfo = $login->login("xxx@example.com", "12345678"); //check $userInfo = $login->check(); if(!$userInfo) //ログインできていな //logout $userInfo = $login->logout();ログイン処理のクラス
ログイン処理のクラスファイルを作成
login.php<?php /* * phpとmysqlでセッションログイン処理を実装するときにとかそういうのを作るのが面倒だったので、exampleを残します。。 * made : ryosuke ando <ryo@ando.link> * */ require_once __DIR__ . "/vendor/autoload.php"; use josegonzalez\Dotenv\Loader as Dotenv; class login { private $dbh; public function __construct() { $appDir = __DIR__; Dotenv::load([ 'filepath' => $appDir . '/.env', 'toEnv' => true ]); $mysqlUser = $_ENV['MYSQL_USER']; $mysqlPass = $_ENV['MYSQL_PASS']; $mysqlHost = $_ENV['MYSQL_HOST']; $mysqlDbName = $_ENV['MYSQL_DBNAME']; $dsn = sprintf("mysql:host=%s;dbname=%s;charset=UTF8", $mysqlHost, $mysqlDbName); try { $this->dbh = new PDO($dsn, $mysqlUser, $mysqlPass); $this->dbh->setAttribute(PDO::ATTR_EMULATE_PREPARES, false); $this->dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); } catch (PDOException $e) { echo "error: " . $e->getMessage() . "\n"; exit(1); } } public function login($email, $password) { /* * ログイン失敗なら、エラーを返します * 成功なら、 */ $sql = "SELECT * FROM users WHERE mail = ?"; $sth = $this->dbh->prepare($sql); $sth->bindParam(1, $email, PDO::PARAM_STR); $sth->execute(); $userInfo = $sth->fetch(PDO::FETCH_ASSOC); if (!$userInfo) //ユーザー名が間違えている return null; if (!password_verify($password, $userInfo['password'])) //パスワードが間違えている return null; session_start(); $_SESSION["user_info"] = $userInfo; return $userInfo; } public function check() { /* * ログインされていれば、ログイン情報を連想配列で返します。 * ログインに失敗しているならば、nullを返します。 */ session_start(); //ログインされているかチェックし、ログイン if (!isset($_SESSION["user_info"])) return null; return $_SESSION["user_info"]; } public function logout() { session_start(); $_SESSION["user_info"] = null; } public function signup($name, $email, $password) { $sql = "INSERT INTO users (`username`,`mail`,`password`) VALUES (?,?,?)"; $sth = $this->dbh->prepare($sql); // echo password_hash($password, PASSWORD_BCRYPT); $sth->bindParam(1, $name, PDO::PARAM_STR); $sth->bindParam(2, $email, PDO::PARAM_STR); $sth->bindParam(3, password_hash($password, PASSWORD_BCRYPT), PDO::PARAM_STR); $sth->execute(); $userInfo = $sth->fetch(PDO::FETCH_ASSOC); session_start(); $_SESSION["user_info"] = $userInfo; return $userInfo; } }https://qiita.com/singlestroke/items/b38f9f9f9b62f2522539
https://qiita.com/KosukeQiita/items/b56b3004413c999b9858
https://qiita.com/zaburo/items/1dd2337c5f9281f7cc3a
https://ja.stackoverflow.com/questions/5053/php-%E3%81%A7%E3%81%AE-sql-%E3%82%A4%E3%83%B3%E3%82%B8%E3%82%A7%E3%82%AF%E3%82%B7%E3%83%A7%E3%83%B3%E5%AF%BE%E7%AD%96%E3%81%AF%E3%81%A9%E3%81%AE%E3%82%88%E3%81%86%E3%81%AB%E8%A1%8C%E3%81%84%E3%81%BE%E3%81%99%E3%81%8B
https://www.php.net/manual/ja/pdostatement.fetch.php
https://qiita.com/rana_kualu/items/3ef57485be1103362f56

























