質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
SendGrid

SendGridは、米SendGrid社のクラウド型メール配信サービス。アカウントを作成するだけですぐに利用することが可能です。さらに到達率向上のための送信ドメイン認証対応や、柔軟性のあるスケーラビリティなど多くの機能を有します。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

トランザクション

トランザクションとは、関連・依存する処理を一連の不可分な処理単位として扱う処理方式を指します。トランザクションとして管理された処理は「すべて成功」か「すべて失敗」のいずれかであることが保証される。処理に失敗した場合は、一連の処理がロールバックされます。

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

Q&A

解決済

1回答

2696閲覧

SendGridのAPIを使用した登録確認メールを phpファイルから実行したい

mocha1325

総合スコア20

SendGrid

SendGridは、米SendGrid社のクラウド型メール配信サービス。アカウントを作成するだけですぐに利用することが可能です。さらに到達率向上のための送信ドメイン認証対応や、柔軟性のあるスケーラビリティなど多くの機能を有します。

PHP

PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

トランザクション

トランザクションとは、関連・依存する処理を一連の不可分な処理単位として扱う処理方式を指します。トランザクションとして管理された処理は「すべて成功」か「すべて失敗」のいずれかであることが保証される。処理に失敗した場合は、一連の処理がロールバックされます。

API

APIはApplication Programming Interfaceの略です。APIはプログラムにリクエストされるサービスがどのように動作するかを、デベロッパーが定めたものです。

0グッド

0クリップ

投稿2021/07/08 04:14

編集2021/07/13 06:41

前提・実現したいこと

お世話になっております。

SendGridのAPIを使用したトランザクションメール(メールアドレス認証を想定)を
ターミナルのphpコマンド以外から実行し送信したいです。

ユーザメールアドレス入力

メールアドレスが登録済みでなければパスコード付き認証メールを送信

という流れで考えているのですが、
条件を満たしたときに
require_once('メール送信ファイル');
ではエラーが出てしまいました。

401 Array ( [0] => HTTP/1.1 401 Unauthorized [1] => Server: nginx [2] => Date: Tue, 13 Jul 2021 05:42:14 GMT [3] => Content-Type: application/json [4] => Content-Length: 88 [5] => Connection: keep-alive [6] => Access-Control-Allow-Origin: https://sendgrid.api-docs.io [7] => Access-Control-Allow-Methods: POST [8] => Access-Control-Allow-Headers: Authorization, Content-Type, On-behalf-of, x-sg-elas-acl [9] => Access-Control-Max-Age: 600 [10] => X-No-CORS-Reason: https://sendgrid.com/docs/Classroom/Basics/API/cors.html [11] => Strict-Transport-Security: max-age=600; includeSubDomains [12] => [13] => ) {"errors":[{"message":"Permission denied, wrong credentials","field":null,"help":null}]}

また、エラー内の文章には下記のように書かれていたのですが、
脆弱性のない書き方はないのでしょうか?
イメージ説明

phpファイル内からexec関数を使い、メール送信の条件が揃ったときに送信ができるようにできるのではないかと思い試してみましたがうまくいきませんでした。
exec関数以外でも大丈夫ですので、ターミナルのphpコマンド以外でメール送信ができる方法があれば教えていただきたいです。

試したこと

ドキュメント
こちらのphpコマンドでメールを送信する方法ではきちんとメールの送信が送れるのですが、
コマンドは使わずphpファイルのみで実行する方法がわかりません。

※ ドキュメントだけでは理解できず、こちらの記事も参考にさせていただきました。

自分なりに探してみたところ、
外部コマンドを実行できるexec関数がヒットしたので、こちらを利用して下記を試しました。

該当のソースコード

php

1<?php 2$cmd1 = 'source .env'; 3exec($cmd1); 4 5$cmd2 = 'cat .env'; 6exec($cmd2, $arr2, $res2); 7var_dump($arr2); 8var_dump($res2); 9 10$cmd3 = 'echo $SENDGRID_API_KEY'; 11exec($cmd3, $arr3, $res3); 12var_dump($arr3); 13var_dump($res3); 14 15$cmd4 = 'php test.php'; 16exec($cmd4, $arr4, $res4); 17var_dump($res4); 18?> 19 20//出力結果 21array(1) { [0]=> string(95) "export SENDGRID_API_KEY='********'" } int(0) array(1) { [0]=> string(0) "" } int(0) int(255) 22

コマンドでは、

$source .env $echo $SENDGRID_API_KEY // APIキー出力 $php test.php 202 Array ( [0] => HTTP/1.1 202 Accepted [1] => Server: ,,, [2] => Date: Thu, 08 Jul 2021 03:48:34 GMT [3] => Content-Length: 0 [4] => Connection: keep-alive [5] => X-Message-Id: ,,,, [6] => Access-Control-Allow-Origin: https://sendgrid.api-docs.io [7] => Access-Control-Allow-Methods: POST [8] => Access-Control-Allow-Headers: Authorization, Content-Type, On-behalf-of, x-sg-elas-acl [9] => Access-Control-Max-Age: 600 [10] => X-No-CORS-Reason: https://sendgrid.com/docs/Classroom/Basics/API/cors.html [11] => Strict-Transport-Security: max-age=600; includeSubDomains [12] => [13] => )

となり、メールはきちんと届きます。
ですが、ファイルからの実行になると、

$echo $SENDGRID_API_KEY

が実行できていません。

補足情報(FW/ツールのバージョンなど)

ちなみにphpファイルにそのまま書く方法も試したのですが、エラーが出ます。

401 Array ( [0] => HTTP/1.1 401 Unauthorized [1] => Server: 、、、 [2] => Date: Thu, 08 Jul 2021 04:10:24 GMT [3] => Content-Type: application/json [4] => Content-Length: 88 [5] => Connection: keep-alive [6] => Access-Control-Allow-Origin: https://sendgrid.api-docs.io [7] => Access-Control-Allow-Methods: POST [8] => Access-Control-Allow-Headers: Authorization, Content-Type, On-behalf-of, x-sg-elas-acl [9] => Access-Control-Max-Age: 600 [10] => X-No-CORS-Reason: https://sendgrid.com/docs/Classroom/Basics/API/cors.html [11] => Strict-Transport-Security: max-age=600; includeSubDomains [12] => [13] => ) {"errors":[{"message":"Permission denied, wrong credentials","field":null,"help":null}]}

契約中のサーバー上にgithub上のファイルをアップして行ったのですが、こちらもあっているのでしょうか?

phpのif文の中にメール送信するコードを書く予定なのですが、
そのようなコードを書いている人が見つけられず、困っています。。

APIを使用した経験があまりないのでめちゃくちゃな書き方をしていると思うのですが
どうかご教授いただけますと大変助かります。m(_ _)m

拙い文章を最後まで読んでいただきありがとうございました。
何卒よろしくお願いいたします。

  • php
  • SendGrid
  • Xサーバー

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yu_1985

2021/07/12 15:36

いまいちなにで詰まっているのかよくわからないのですが、コマンドで実行できるならそのphpをそのままそれ以外でも適当に呼び出せば実行できるのではないでしょうか? ファイルからの実行とは具体的に何をしたいのでしょう? 見た感じ単に環境変数の読み込みに失敗しているだけな気がするので、php内で適切に環境変数を設定するか、シェルスクリプトでまとめて処理を呼び出すかすれば良い気がしますが…。
mocha1325

2021/07/13 06:26

お世話になっております。 require_onceでphpファイルの実行を試みたのですが出来なかったため、その他の方法を使い原因が突き止められないかと思いexec関数でも試してみていました。 「環境変数」という言葉を恥ずかしながら知らなかったためもう一度調べさせていただきます!ご意見ありがとうございます!
guest

回答1

0

ベストアンサー

SENDGRID_API_KEYに何も値をセットしてないなら当然うまく行かないので、どこかしらで値をセットしてください。
コマンドラインでテスト実行するときには.envに定義した変数を手動でコマンドで読み込んでからやっていますが、コマンドラインではなくプログラムの実行ユーザに環境変数を読ませるには別の方法を取る必要があります。

.envファイルが既にあるならphpdotenvを使うのが簡単です。
【PHP】環境変数(.env)を読み込む

投稿2021/07/13 06:38

yu_1985

総合スコア7445

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

mocha1325

2021/07/13 07:13

ご回答ありがとうございます。 現在 .envにexport SENDGRID_API_KEY='*********'でSENDGRID_API_KEYを定義している状態で、 ファイル内は下記のようになっています。 -----test.php------------------------------ <?php require 'vendor/autoload.php'; // If you're using Composer (recommended) $email = new \SendGrid\Mail\Mail(); $email->setFrom("test@example.com", "Example User"); $email->setSubject("Sending with SendGrid is Fun"); $email->addTo("myaddress", "Example User"); $email->addContent("text/plain", "and easy to do anywhere, even with PHP"); $email->addContent( "text/html", "<strong>and easy to do anywhere, even with PHP</strong>" ); $sendgrid = new \SendGrid(getenv('SENDGRID_API_KEY')); try { $response = $sendgrid->send($email); print $response->statusCode() . "\n"; print_r($response->headers()); print $response->body() . "\n"; } catch (Exception $e) { echo 'Caught exception: '. $e->getMessage() ."\n"; } -------------------------------------------------- 宛先メールアドレス以外ドキュメントのコピペにしている状態で、 コマンドからはphp test.phpで送信ができているので、phpdotenvを使いgetenv() で呼び出せているように思うのですが、呼び出し方法に間違いがあるのでしょうか?m(_ _)m
yu_1985

2021/07/13 07:25

.envの設定の仕方が違います。 exportはコマンドですが、.envではそうではなく単純に SENDGRID_API_KEY='*********' と記載してください。 コマンドラインではsource .envで先に.envを読み込んでいるからうまくいくのであって、それをしてなければgetenv()で取得すべき変数がプログラム実行時に設定されていないのでは。 説明が重複しますが、コマンドラインではなくプログラムの実行ユーザに環境変数を読ませるには別の方法を取る必要があります。 そこでphpdotenvを使ってはどうですか、とここでは言っています。
mocha1325

2021/07/13 14:04

ご返信ありがとうございます! こちらの理解が及ばず、お手数おかけしてしまい申し訳ございませんでした。 教えていただいたブログを元に、.evnのexportをなくし、source .envなしで、「php test.php」のみで実行できるファイルの作成ができました!ありがとうございます! ---test.php------------------------------------- <?php require 'vendor/autoload.php'; $dotenv = Dotenv\Dotenv::createImmutable(__DIR__); $dotenv->load(); echo $_ENV["SENDGRID_API_KEY"]; -------------------------------------------------- ですが、こちらもtest.phpをアップロードした先へのアクセスやrequireでは Fatal error: Uncaught Error: Class 'Dotenv\Dotenv' not found となってしまいます。 他の書き方も試してみましたが、コマンドからは上手くいき、アップロード先ではエラーが出るため何か重要なファイルを見逃しているのかとも考えたのですが、わかりません。 composer.json composer.lock もアップロード済みなのですが、他にどのようなことを行えばコマンドでの実行と同じように動いてくれますでしょうか。 色々と調べさせていただいたのですが、恥ずかしながら自分の力では辿り着けず露頭に迷っております。 何卒よろしくお願いいたします。
yu_1985

2021/07/13 14:32

アップロード先と言ってるのは、コマンド実行したのはローカルで、プログラムを実行させているのは別の環境ということでしょうか。 環境が違うならそもそも前提が違うのでそこについてもう少し記載してください。アップロードと言っていますが、どのようにデプロイしているのかも不明ですし。 エラーを見る限り、アップロード先ではphpdotenvがインストールできていないのでは? 動作環境がわかりませんがアップロード後にcomposer installなどはしましたか?
mocha1325

2021/07/20 01:43

お返事が遅くなってしまい大変申し訳ございません。 yu_1985様のおかげで環境が原因であることがわかり、環境を同じようにしたところ、phpdotenvを使って環境変数を読ませることができました! 初歩的な部分の理解がなくご迷惑おかけしました。 自分に足りない部分がわかりとても勉強になりました!ありがとうございました!!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問