<?xml version="1.0" encoding="UTF-8"?><rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>PHP IMAP  |  takeHo（たけほ）のへなちょこ台帳</title>
	<atom:link href="https://blog.takeho.com/tag/php-imap/feed/" rel="self" type="application/rss+xml" />
	<link>https://blog.takeho.com</link>
	<description>いわゆる自由帳ってところです。</description>
	<lastBuildDate>Fri, 07 Feb 2025 10:42:43 +0000</lastBuildDate>
	<language>ja</language>
	<sy:updatePeriod>
	hourly	</sy:updatePeriod>
	<sy:updateFrequency>
	1	</sy:updateFrequency>
	<generator>https://wordpress.org/?v=6.6</generator>

<image>
	<url>https://blog.takeho.com/wp-content/uploads/2024/08/icon-150x150.png</url>
	<title>PHP IMAP  |  takeHo（たけほ）のへなちょこ台帳</title>
	<link>https://blog.takeho.com</link>
	<width>32</width>
	<height>32</height>
</image> 
	<item>
		<title>Yii2でメールサーバから受信ボックスのデータを取得</title>
		<link>https://blog.takeho.com/retrieve-inbox-data-from-mail-server-with-yii2/</link>
					<comments>https://blog.takeho.com/retrieve-inbox-data-from-mail-server-with-yii2/#respond</comments>
		
		<dc:creator><![CDATA[たけほ]]></dc:creator>
		<pubDate>Tue, 04 Feb 2025 14:41:00 +0000</pubDate>
				<category><![CDATA[Yii2]]></category>
		<category><![CDATA[PHP IMAP]]></category>
		<guid isPermaLink="false">https://blog.takeho.com/?p=608</guid>

					<description><![CDATA[Yii2でGmailやYahooメールを受信するコンポーネントを作成してみました。 目次 コンポーネントの開発ディレクトリ・ファイルの作成ファイルの作成使い方設定実行例InboxControllerViewファイルブラウ [&#8230;]]]></description>
										<content:encoded><![CDATA[
<p>Yii2でGmailやYahooメールを受信するコンポーネントを作成してみました。</p>



<div class="wp-block-cocoon-blocks-tab-caption-box-1 tab-caption-box block-box not-nested-style cocoon-block-tab-caption-box"><div class="tab-caption-box-label block-box-label box-label"><span class="tab-caption-box-label-text block-box-label-text box-label-text">注意事項</span></div><div class="tab-caption-box-content block-box-content box-content">
<p>PHP IMAP関数が有効である必要があります。</p>
</div></div>




  <div id="toc" class="toc tnt-number toc-center tnt-number border-element"><input type="checkbox" class="toc-checkbox" id="toc-checkbox-2"><label class="toc-title" for="toc-checkbox-2">目次</label>
    <div class="toc-content">
    <ol class="toc-list open"><li><a href="#toc1" tabindex="0">コンポーネントの開発</a><ol><li><a href="#toc2" tabindex="0">ディレクトリ・ファイルの作成</a></li><li><a href="#toc3" tabindex="0">ファイルの作成</a></li></ol></li><li><a href="#toc4" tabindex="0">使い方</a><ol><li><a href="#toc5" tabindex="0">設定</a></li><li><a href="#toc6" tabindex="0">実行例</a><ol><li><a href="#toc7" tabindex="0">InboxController</a></li><li><a href="#toc8" tabindex="0">Viewファイル</a></li><li><a href="#toc9" tabindex="0">ブラウザで確認</a></li></ol></li></ol></li></ol>
    </div>
  </div>

<h2 class="wp-block-heading"><span id="toc1">コンポーネントの開発</span></h2>



<h3 class="wp-block-heading"><span id="toc2">ディレクトリ・ファイルの作成</span></h3>



<p>アプリケーションディレクトリ内に<strong>components</strong>ディレクトリを作成します。</p>



<p>次にそのディレクトリの中に<strong>MailFetcherComponent.php</strong>のファイルを次の内容で作成します。</p>



<h3 class="wp-block-heading"><span id="toc3">ファイルの作成</span></h3>



<pre class="wp-block-code"><code>&lt;?php

namespace app\components;
    
use Yii;
use yii\base\Component;
use yii\base\Exception;

class MailFetcherComponent extends Component
{
    // Kind ( SMTP / IMAP / POP3 ).
    public $kind;
    
    // Mail server.
    public $host;
    
    // Connect post.
    public $port;
    
    // Account user.
    public $username;
    
    // Account password.
    public $password;
    
    // Encrypt type ( PLAIN / LOGIN / CRAM-MD5 ).
    public $encryption;
    
    // Target mail folder.
    public $mailboxFolder = 'INBOX';
    
    // Seaving server directoy for attachments.
    public $attachmentPath = false;
    
    protected $inbox;
    
    public function init()
    {
        parent::init();
        
        if (!$this->host || !$this->username || !$this->password) {
            throw  new \Exception("メールサーバの情報が不足しています。");
        }
        
    }
    
    public function connectOpen($args = &#91;])
    {
        $labels = &#91; 'kind', 'host', 'port', 
                    'encryption', 'mailboxFolder'];
        
        $connectSource = "{{host}:{port}/{kind}/{encryption}}{mailboxFolder}";
        
        foreach ($labels as $label){
            if (isset($args&#91;$label])) {
                $this->$label = $args&#91;$label];
            }
            if (in_array($label, &#91;'username', 'password'])) continue;
            
            $val = $label == 'mailboxFolder' ? 
                    strtoupper($this->$label) : 
                    strtolower($this->$label); 
            
            $connectSource = str_replace('{'.$label.'}', $val, $connectSource);
        }

        $this->inbox = imap_open($connectSource, $this->username, $this->password);
        
        if (!$this->inbox) {
            echo "IMAP接続に失敗しました: " . imap_last_error();
            return;
        }
        
        if (!$this->attachmentPath) {
            $this->attachmentPath = Yii::getAlias('@runtime/mail_attachments');
        }
        
        if (!is_dir($this->attachmentPath)) {
            mkdir($this->attachmentPath, 0777, true);
        }
    }
    
    public function fetchMails($searchCriteria = 'ALL')
    {
        $sources = &#91;];
        
        $emails = imap_search($this->inbox, $searchCriteria);
        
        if ($emails) 
        {
            rsort($emails); // 最新のメールが最初に表示されるようにソート

            foreach ($emails as $emailNumber) 
            {
                $overview = imap_fetch_overview($this->inbox, $emailNumber, 0);
                
                // サブジェクトのデコード
                $subject = $this->mimeDecode($overview&#91;0]->subject);

                // 差出人のデコード
                $from = $this->mimeDecode($overview&#91;0]->from);
                
                $structure = imap_fetchstructure($this->inbox, $emailNumber);
                $message = '';
                
                
                if ($structure->type == 1) { // マルチパートメールの場合
                    
                    $attachments = array();
                    foreach ($structure->parts as $partNumber => $part) {
                        if ($part->subtype == 'PLAIN') {
                            $message = imap_fetchbody($this->inbox, $emailNumber, $partNumber + 1);

                            if ($part->encoding == 3) { // BASE64
                                $message = base64_decode($message);
                            } elseif ($part->encoding == 4) { // QUOTED-PRINTABLE
                                $message = quoted_printable_decode($message);
                            }
                            break;
                        }
                        
                        // 添付ファイルの取得
                        if (isset($part->disposition) &amp;&amp; strtolower($part->disposition) == 'attachment') {
                            $attachment = imap_fetchbody($this->inbox, $emailNumber, $partNumber + 1);

                            if ($part->encoding == 3) { // BASE64
                                $attachment = base64_decode($attachment);
                            } elseif ($part->encoding == 4) { // QUOTED-PRINTABLE
                                $attachment = quoted_printable_decode($attachment);
                            }

                            $filename = 'attachment_' . time() . '_' . ($part->dparameters&#91;0]->value ?? 'unknown');
                            file_put_contents($this->attachmentPath . '/' . $filename, $attachment);
                            $attachments&#91;] = $this->attachmentPath . '/' . $filename;
                            echo "添付ファイルを保存しました: " . $filename . "\n";
                        }
                    }
                } else { // 単一パートメールの場合
                    $message = imap_fetchbody($this->inbox, $emailNumber, 1);

                    // エンコードの処理
                    if ($structure->encoding == 3) { // BASE64
                        $message = base64_decode($message);
                    } elseif ($structure->encoding == 4) { // QUOTED-PRINTABLE
                        $message = quoted_printable_decode($message);
                    }
                }

                $sources&#91;$emailNumber] = &#91;
                    'Subject' => $subject,
                    'From' => $from,
                    'Date' => $overview&#91;0]->date,
                    'Message' => $message,
                ];
            }
        }
        
        imap_close($this->inbox);
        
        return $sources;
    }
    
    private function mimeDecode($str = '')
    {
        $encode_array = isset($str) ? imap_mime_header_decode($str) : &#91;];
        $decoded      = '';
        foreach ($encode_array as $part) {
            $decoded .= $part->text;
        }
        
        return $decoded;
    }   
}</code></pre>



<h2 class="wp-block-heading"><span id="toc4">使い方</span></h2>



<h3 class="wp-block-heading"><span id="toc5">設定</span></h3>



<p>設定ファイル（config/web.php）に作成したMailFetcherコンポーネントを次のように追加します。</p>



<pre class="wp-block-code"><code>    'components' => &#91;
        'mailFetcher' => &#91;
            'class' => 'app\components\MailFetcherComponent',
            'kind' => 'IMAP',
            'host' => 'メールサーバホスト名',  // IMAPサーバーのホスト名
            'username' => 'アカウントユーザー名',
            'password' => 'パスワード',
            'port' => 'ポート',
            'encryption' => '暗号化タイプ',
            'mailboxFolder' => 'INBOX',  // デフォルトでINBOXを使用
        ],</code></pre>



<p>上記の設定でコンポーネントをコントローラー上で実行できるようになります。</p>



<pre class="wp-block-code"><code>Yii::$app->mailFetcher;</code></pre>



<h3 class="wp-block-heading"><span id="toc6">実行例</span></h3>



<h4 class="wp-block-heading"><span id="toc7">InboxController</span></h4>



<p>InboxControllerを次のように作成します。</p>



<pre class="wp-block-code"><code>&lt;?php

namespace app\controllers;

use Yii;
use app\models\Account;

class InboxController extends \yii\web\Controller
{
    public function actionIndex()
    {
        $receiver= Yii::$app->mailFetcher;
        
        $receiver->connectOpen();
        
        return $this->render('index', &#91;
            'receiver' => $receiver->fetchMails('ALL'),
        ]);
    }
}</code></pre>



<h4 class="wp-block-heading"><span id="toc8">Viewファイル</span></h4>



<p><strong>/views/inbox/index.php</strong>を次にように編集します。</p>



<pre class="wp-block-code"><code>&lt;?php
/** @var yii\web\View $this */
?>
&lt;h1>inbox/index&lt;/h1>

&lt;p>
    You may change the content of this page by modifying
    the file &lt;code>&lt;?= __FILE__; ?>&lt;/code>.
&lt;/p>
&lt;h2>Receiver Result&lt;/h2>

&lt;?php foreach($receiver as $email): ?>

&lt;div style="padding:1em;margin-bottom:3em;border:solid 3px #999;">
    &lt;dl>
        &lt;dt>Date&lt;/dt>
        &lt;dd>&lt;?php echo $email&#91;'Date'] ?>&lt;/dd>
        &lt;dt>From&lt;/dt>
        &lt;dd>&lt;?php echo $email&#91;'From'] ?>&lt;/dd>
        &lt;dt>Subject&lt;/dt>
        &lt;dd>&lt;?php echo $email&#91;'Subject'] ?>&lt;/dd>
        &lt;dt>Message&lt;/dt>
        &lt;dd>&lt;?php echo nl2br($email&#91;'Message']) ?>&lt;/dd>
    &lt;/dl>
&lt;/div>
&lt;?php endforeach; ?></code></pre>



<h4 class="wp-block-heading"><span id="toc9">ブラウザで確認</span></h4>



<p>次のURLへアクセスして確認します。</p>



<pre class="wp-block-code"><code>http:&#47;&#47;ホスト名/index.php?r=inbox/index</code></pre>



<figure class="wp-block-image size-full"><img fetchpriority="high" decoding="async" width="1000" height="683" src="https://blog.takeho.com/wp-content/uploads/2025/02/3483292.png" alt="" class="wp-image-615" srcset="https://blog.takeho.com/wp-content/uploads/2025/02/3483292.png 1000w, https://blog.takeho.com/wp-content/uploads/2025/02/3483292-640x437.png 640w, https://blog.takeho.com/wp-content/uploads/2025/02/3483292-768x525.png 768w" sizes="(max-width: 1000px) 100vw, 1000px" /></figure>



<p>メールの受信ボックス情報が確認できれば成功です。</p>
]]></content:encoded>
					
					<wfw:commentRss>https://blog.takeho.com/retrieve-inbox-data-from-mail-server-with-yii2/feed/</wfw:commentRss>
			<slash:comments>0</slash:comments>
		
		
			</item>
	</channel>
</rss>
