カテゴリー: PHP

【Symfony2】ScopeCrossingInjectionException ・・・

ScopeCrossingInjectionException ・・・
のエラーが出た時のメモ

use JMS\DiExtraBundle\Annotation as DI;

アノテーションを利用していて以下のようにInjectをした時にエラーが出た。

    /**
     * Constructor.
     *
     * @DI\InjectParams({
     *     "validatorHelper" = @DI\Inject("xxx_util.validator_helper"),
     * })
     * @param ValidatorHelperInterface $validatorHelper
     */
    public function __construct(
        ValidatorHelperInterface $validatorHelper
    ) {
        $this->injectedValidatorHelper = $validatorHelper;
    }

ScopeCrossingInjectionException: Scope Crossing Injection detected: The definition “************” references the service “xxx_util.validator_helper” which belongs to another scope hierarchy.
This service might not be available consistently.
Generally, it is safer to either move the definition “************” to scope “prototype”, or declare “container” as a child scope of “prototype”.
If you can be sure that the other scope is always active,
you can set the reference to strict=false to get rid of this error.

エラー文の最後に書いてあるように「strict=false」を追加すれば通った。

    /**
     * Constructor.
     *
     * @DI\InjectParams({
     *     "validatorHelper" = @DI\Inject("xxx_util.validator_helper", strict = false),
     * })
     * @param ValidatorHelperInterface $validatorHelper
     */
    public function __construct(
        ValidatorHelperInterface $validatorHelper
    ) {
        $this->injectedValidatorHelper = $validatorHelper;
    }

エラーをちゃんと最後まで読もう・・・。
■参考URL
Bundles/JMSDiExtraBundle/Annotations
http://jmsyst.com/bundles/JMSDiExtraBundle/master/annotations#inject

【phpStorm】SSH Terminalで接続して日本語が文字化ける場合

phpStorm

出来るだけ開発中に開くツールを減らすべく、
TerminalをphpStormのものに変更する。

SSH Terminalに接続して日本語が文字化ける場合↓

「File」->「Settings」->「Tools」->「SSH Terminal」

「Default encoding」を「UTF-8」に変更。

Terminalを「Floting Mode」で利用する場合デフォルトでは
Terminalを最小化する ->「Shift」+「Esc」
Terminalを表示する -> 「Alt」+「F12」
データベース接続もphpStormのものを利用するようにする。
「View」 -> 「Tool Windows」 -> 「Database」

【FuelPHP】FuelPHPでdompdfを使うまでの道のり

【FuelPHP】FuelPHPでdompdfを使うまでの道のり

前回まではoilコマンドで「fuel/packages/pdf」に
fuel-pdfをインストールして使っていたけど、
フォントのインストールしたり、設定ファイルを色々と
変更するなどしていると管理が面倒になったので、
fuel-pdfをやめて、dompdf自体を「fuel/app/vendor」
にいれて管理するように変更した。

前回のインストールの様子
【FuelPHP】FuelPHPでfuel-pdfを使うまでの道のり

dompdf自体をgitで設置することで前回までに起きていた
クラスが見つからない問題などが一切でなかったので、
こっちのやり方のほうが安心できる。
同梱されてる「tcpdf」使って無いしこれで問題ない。

とりえあず設定方法のメモ。

■fuel/app/vendor以下にdompdfをいれるので移動。

$ pwd
/home/linux-user/public_html/tmp/appname/fuel/app/vendor

■dompdfをcloneする

$ git clone https://github.com/dompdf/dompdf.git
Initialized empty Git repository in /home/linux-user/public_html/tmp/appname/fuel/app/vendor/dompdf/.git/
remote: Counting objects: 5634, done.
remote: Total 5634 (delta 0), reused 0 (delta 0), pack-reused 5634
Receiving objects: 100% (5634/5634), 13.47 MiB | 3.40 MiB/s, done.
Resolving deltas: 100% (3967/3967), done.

■できたフォルダに移動して・・・

$ cd dompdf/

■サブモジュールのinitとupdateで空になってた「php-font-lib」が入ります。

$ git submodule init
Submodule 'lib/php-font-lib' (https://github.com/PhenX/php-font-lib.git) registered for path 'lib/php-font-lib'

$ git submodule update
Initialized empty Git repository in /home/linux-user/public_html/tmp/appname/fuel/app/vendor/dompdf/lib/php-font-lib/.git/
remote: Counting objects: 885, done.
remote: Total 885 (delta 0), reused 0 (delta 0), pack-reused 885
Receiving objects: 100% (885/885), 9.25 MiB | 1.82 MiB/s, done.
Resolving deltas: 100% (493/493), done.
Submodule path 'lib/php-font-lib': checked out 'c30c7fc00a6b0d863e9bb4c5d5dd015298b2dc82'

■マルチバイト対応のためにIPAフォントを準備
(前回のインストール時に/home/linux-user/.fonts/にダウンロード済み)

$ php load_font.php ipagothic /home/linux-user/.fonts/IPAfont00303/ipagp.ttf
Unable to find bold face file.
Unable to find italic face file.
Unable to find bold_italic face file.
Copying /home/linux-user/.fonts/IPAfont00303/ipagp.ttf to /home/linux-user/public_html/tmp/appname/fuel/app/vendor/dompdf/lib/fonts/ipagp.ttf...
Generating Adobe Font Metrics for /home/linux-user/public_html/tmp/appname/fuel/app/vendor/dompdf/lib/fonts/ipagp...

■テスト用のコントローラを作成して実行

public function action_pdftest()
{
    require_once( APPPATH .'vendor/dompdf/dompdf_config.inc.php');
    $pdf = new \DOMPDF();
    $html ='<!DOCTYPE html>
        <html>
        <head>
        <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
        <title>xxx</title>
        <style>
        body { font-family: "ipagothic;" }
        </style>
        </head>
        <body>
        マルチバイト
        </body>
        </html>';
    $pdf->load_html($html);
    $pdf->render();
    $pdf->stream("sample.pdf", array("Attachment" => 0));
}

dompdf/dompdf
https://github.com/dompdf/dompdf

Usage dompdf
https://github.com/dompdf/dompdf/wiki/Usage

【PHP】phpでstrftimeを使って和暦や午前、午後のフォーマットで表示する方法

phpでstrftimeを使って和暦や午前、午後のフォーマットで表示する方法

Linux環境で試したらできた。
(Cライブラリに依存するらしいです。)

setlocale(LC_TIME, "ja_JP.utf8", "Japanese_Japan.932");
print strftime('%EC%Ey年%B%#d日(%A) %OP %I時%M分', strtotime('2015-02-26 11:30:00'));
平成27年2月26日(木曜日) 午前 11時30分

■参考URL

strftimeで和暦表示
http://qiita.com/iwykzm@github/items/e6ff9f735a8ac7998a72

strftime – convert date and time to a string
http://pubs.opengroup.org/onlinepubs/007908799/xsh/strftime.html

【FuelPHP】dompdfで作成するPDFのサイズを小さくしてみる

dompdfで作成するPDFのサイズを小さくしてみる

前回dompdfを使ってHTMLからPDFを生成できるようになったのですが、
どうもPDFにフォントが全て含まれているようでファイルサイズがでかかった。
そこで設定を変更して利用しているフォントだけを含むようにしてみる。

■dompdf_config.custom.inc.php

//define("DOMPDF_ENABLE_FONTSUBSETTING", true);
// ↓
define("DOMPDF_ENABLE_FONTSUBSETTING", true);

上記の設定変更で問題無いはずだけど以下のエラーが発生。

Fatal Error - Class 'Font' not found in /****/fuel/packages/pdf/lib/dompdf/lib/class.pdf.php on line 2352
// Load font
$font_obj = Font::load($fbfile);

上記のFontクラスが読めていない模様。
そもそも前回パスを勝手に変更して設置しているのでその影響かもしれない。
とりあえず該当クラスでFontが読めるように数行追記

■packages/pdf/lib/dompdf/lib/class.pdf.php

require_once "php-font-lib/classes/Autoloader.php";
use FontLib\Font;

実行するとさらに以下のエラーが発生。

Fatal Error - Class 'Font_Binary_Stream' not found in /****/fuel/packages/pdf/lib/dompdf/lib/class.pdf.php on line 2367

php-font-lib/classesの下を見ても「Font_Binary_Stream」は無いので、
名前が似ている「Binary_Stream」を利用するように変更してみる。

■packages/pdf/lib/dompdf/lib/class.pdf.php

require_once "php-font-lib/classes/Autoloader.php";
use FontLib\Font;
use FontLib\Binary_Stream;

■packages/pdf/lib/dompdf/lib/class.pdf.php @2367くらい

//$font_obj->open($tmp_name, Font_Binary_Stream::modeWrite);
//↓
$font_obj->open($tmp_name, Binary_Stream::modeWrite);

実行すると動いた。
元々4.3MBあったPDFが39KBに激減した。

これでいいのかな・・・・?

■参考サイト
DOMPDFでPDFファイルサイズを小さくする
http://madroom-project.blogspot.jp/2012/12/dompdfpdf.html

【FuelPHP】FuelPHPでfuel-pdfを使うまでの道のり

FuelPHPでfuel-pdfを使うまでの道のり

HTMLをPDFとして出力したいのでfuel-pdfをインストールしdompdfを使ってみる。
設定するまでにかなりてこずったのでメモ。

fuel-pdfをoilコマンドでいれるよりも、dompdfをそのまま
インストールしたほうがフォントのインストールとかも考えたら
やりやすいかもしれない。
【FuelPHP】FuelPHPでdompdfを使うまでの道のり

 

■fuel-pdfをインストール

$ php oil package install pdf

■フォルダ名を変更する
「fuel/packages/fuel-pdf」から
「fuel/packages/pdf」に変更

■利用できるようにconfigを変更

編集ファイル:「fuel/app/config/config.php」

	 'always_load'  => array(

		 'packages'  => array(
             'pdf'
		),

		・・・
		),

■とりあえず動かすために適当なコントローラを用意して以下を記述

    public function action_hoge()
    {

        \Package::load('pdf');
        $pdf = \Pdf::factory('dompdf')->init();

        $html ='<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>xxx</title>
<style>
body { font-family: "ipagothic;" }
</style>
</head>
<body>
マルチバイト
</body>
</html>';

        $pdf->load_html($html);
        $pdf->render();
        $pdf->stream("test.pdf");
    }

この状態でPDFがダウンロードできるが????とか文字化けしている状態のはず。

■日本語が表示できるフォントが無いのでIPAフォントをインストールする

まずIPAのサイトにしたがってフォントをサーバにインストールする。

Linuxに対するフォントインストール例
http://ipafont.ipa.go.jp/fontinstall.html

■dompdfを最新のものに変更

まず最初に。。
http://madroom-project.blogspot.jp/2012/11/fuel-pdfhtmlpdf.html
このサイトに沿って

pdf/lib/dompdfと
pdf/lib/dompdf/lib/php-font-lib
を差し替える

■次にdompdf側でIPAフォントをロードする

以下のコマンドでロードを行う模様

$ php load_font.php ipagothic /home/user/.fonts/IPAfont00303/ipagp.ttf

しかし失敗

$ php load_font.php ipagothic /home/user/.fonts/IPAfont00303/ipagp.ttf
PHP Warning:  require_once(/home/user/public_html/bantane/cooperation/fuel/packages/pdf/lib/dompdf/lib/php-font-lib/classes/Font.php): failed to open stream: No such file or directory in /home/user/public_html/bantane/cooperation/fuel/packages/pdf/lib/dompdf/dompdf_config.inc.php on line 332
PHP Fatal error:  require_once(): Failed opening required '/home/user/public_html/bantane/cooperation/fuel/packages/pdf/lib/dompdf/lib/php-font-lib/classes/Font.php' (include_path='.:/usr/share/pear:/usr/share/php') in /home/user/public_html/bantane/cooperation/fuel/packages/pdf/lib/dompdf/dompdf_config.inc.php on line 332

「fuel/packages/pdf/lib/dompdf/lib/php-font-lib/classes/Font.php」
↑これが無いっていっている

dompdf fails to load
http://stackoverflow.com/questions/15028250/dompdf-fails-to-load

↑このページを参考にして
「php-font-lib/src/FontLib」を「php-font-lib/classes/」として配置する。

$ cd fuel/packages/pdf/lib/dompdf/lib/php-font-lib/src
$ cp -r FontLib ../classes
$ pwd
/home/user/public_html/bantane/cooperation/fuel/packages/pdf/lib/dompdf/lib/php-font-lib/classes
$ ll
合計 68
drwxrwxr-x 8 user user 4096  2月 24 16:49 2015 ./
drwxrwxr-x 7 user user 4096  2月 24 16:49 2015 ../
-rw-rw-r-- 1 user user 5867  2月 24 16:49 2015 Adobe_Font_Metrics.php
-rw-rw-r-- 1 user user  986  2月 24 16:49 2015 Autoloader.php
-rw-rw-r-- 1 user user 8715  2月 24 16:49 2015 Binary_Stream.php
drwxrwxr-x 2 user user 4096  2月 24 16:49 2015 EOT/
-rw-rw-r-- 1 user user  836  2月 24 16:49 2015 Encoding_Map.php
-rw-rw-r-- 1 user user 1606  2月 24 16:49 2015 Font.php
drwxrwxr-x 2 user user 4096  2月 24 16:49 2015 Glyph/
-rw-rw-r-- 1 user user  725  2月 24 16:49 2015 Header.php
drwxrwxr-x 2 user user 4096  2月 24 16:49 2015 OpenType/
drwxrwxr-x 3 user user 4096  2月 24 16:49 2015 Table/
drwxrwxr-x 2 user user 4096  2月 24 16:49 2015 TrueType/
drwxrwxr-x 2 user user 4096  2月 24 16:49 2015 WOFF/

このようにしてFont.phpがある状態にする

しかしまだ失敗。。

$ php load_font.php ipagothic /home/user/.fonts/IPAfont00303/ipagp.ttf
Unable to find bold face file.
Unable to find italic face file.
Unable to find bold_italic face file.
Copying /home/user/.fonts/IPAfont00303/ipagp.ttf to /home/user/public_html/bantane/cooperation/fuel/packages/pdf/lib/dompdf/lib/fonts/ipagp.ttf...
Generating Adobe Font Metrics for /home/user/public_html/bantane/cooperation/fuel/packages/pdf/lib/dompdf/lib/fonts/ipagp...
PHP Fatal error:  Class 'Font' not found in /home/user/public_html/bantane/cooperation/fuel/packages/pdf/lib/dompdf/load_font.php on line 139

DOMPDF – Class ‘Font’ not found
http://stackoverflow.com/questions/22226218/dompdf-class-font-not-found

↑このページを参考にload_font.phpを変更

require_once "dompdf_config.inc.php";

↓以下に変更する

require_once "dompdf_config.inc.php";
require_once "lib/php-font-lib/classes/Autoloader.php";
use FontLib\Font;

やっと成功。

$ php load_font.php ipagothic /home/user/.fonts/IPAfont00303/ipagp.ttf
Unable to find bold face file.
Unable to find italic face file.
Unable to find bold_italic face file.
Copying /home/user/.fonts/IPAfont00303/ipagp.ttf to /home/user/public_html/bantane/cooperation/fuel/packages/pdf/lib/dompdf/lib/fonts/ipagp.ttf...
Generating Adobe Font Metrics for /home/user/public_html/bantane/cooperation/fuel/packages/pdf/lib/dompdf/lib/fonts/ipagp...

load_font.phpは無事に動いた。

この状態でプログラムを動かすとPDFに日本語が表示された。

■参考サイト

TJS-Technology/fuel-pdf
https://github.com/TJS-Technology/fuel-pdf

FuelPHP の fuel-pdf パッケージを利用し日本語の PDF を生成する
http://qiita.com/hmukaida/items/a960408e736b079390ef

dompdf
https://code.google.com/p/dompdf/wiki/Installation

dompdfで日本語を扱う
http://www.yazin.info/blog/archives/2012/0719_203107.html

FuelPHPのfuel-pdfパッケージをセットアップしてHTMLをPDFにコンバートして出力
http://madroom-project.blogspot.jp/2012/11/fuel-pdfhtmlpdf.html

Unable to locate the ttf2afm / ttf2pt1 executable
http://stackoverflow.com/questions/21675533/unable-to-locate-the-ttf2afm-ttf2pt1-executable

dompdf fails to load
http://stackoverflow.com/questions/15028250/dompdf-fails-to-load

DOMPDF – Class ‘Font’ not found
http://stackoverflow.com/questions/22226218/dompdf-class-font-not-found

dompdf samples
http://pxd.me/dompdf/www/examples.php#encoding_utf-8.html,pdf

CodeIgniterで「Disallowed Key Characters. __utmt_~1」

「Disallowed Key Characters. __utmt_~1」

CodeIgniterで作成したシステムで上記のエラーが
出るようになった。

原因は1ページ内にGoogle Analyticsのタグを複数
記述してしまったことが原因らしい。

タグを1つにして「~」のついているCookieを削除して解決。

ただCookieに入った「__utmt_~1」の「~」の影響で
「Disallowed Key Characters.」が出るのが気持ち悪い。。

Input.phpの「_clean_input_keys」に「~」を追加するやり方を
してる人もいた。

Disallowed Key Characters – Codeigniter urgent
http://stackoverflow.com/questions/26145721/disallowed-key-characters-codeigniter-urgent

Hunting Down the CodeIgniter “Disallowed Key Characters” Error
http://wejn.com/blog/2014/10/hunting-down-the-codeigniter-disallowed-key-characters-error/

get_headersでhttpsにアクセスしたらエラーが出たのでcurlにしたメモ

get_headersでhttpsにアクセスしたらエラーが出たのでcurlにしたメモ

リンク切れチェックのためにget_headersでhttpsのページにアクセスしたら以下のエラーが出たのでその対処方法

PHP Warning:  get_headers(): Failed to enable crypto in ...

とりあえずget_headersをあきらめてhttpsのときはcurlを利用するように変更した。

以下完成形。

$url = 'https://example.com/aaa/bbb';
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HEADER, true);
curl_setopt($ch, CURLOPT_SSLVERSION, 1);
if(curl_exec($ch) === false)
{
 echo 'Curl error: ' . curl_error($ch);
}

$info = curl_getinfo($ch);
echo $info['http_code'];
curl_close($ch);     

上記のコードでhttpsの場合のステータスコードが
取得できるようになった。

エラーを取得しておかないとなんでエラーになったか不明なので
以下のところが大事かも。

if(curl_exec($ch) === false)
{
 echo 'Curl error: ' . curl_error($ch);
}

あと、特定のURLにアクセスした際に以下のエラーがでました。

Curl error: Unknown SSL protocol error in connection to ...

これはPHPが自動で設定しているSSLプロトコルでは駄目と
いうことらしいので

curl_setopt($ch, CURLOPT_SSLVERSION, 1);

上記のように「TLSv1」を指定しました。

その他のCURLOPT_SSLVERSIONは以下のページに記載されてます。
curl_setopt
http://php.net/manual/ja/function.curl-setopt.php

Apache2.4でob_flushが動かなかったメモ

新しいCPIの専用サーバにシステムを設置した際にob_flushが
動作しなかったのでそのメモ。

結局、Apache2.4から導入されているmod_deflate というモジュールが原因ということでした。

mod_deflateとは?

クライアントへ送られる前にコンテンツを圧縮するモジュール

mod_deflateが有効になっているとクライアントへ送る前に圧縮するので
ob_flushの都度の出力がまとめられて圧縮されてまとめられてしまっているようです。

とりあえずPHPファイルで圧縮しないようにするhtaccessは以下でいいみたいです。

.htaccessファイル

<Files ~ "\.php">
  SetEnv no-gzip
</Files>

■参考
Apache モジュール mod_deflate
http://httpd.apache.org/docs/current/ja/mod/mod_deflate.html

Apacheのmod_deflateでコンテンツを圧縮してサイトを高速化する方法
http://oxynotes.com/?p=6519

PHPとBootstrap3でプログレスバーの表示

PHPとBootstrap3でプログレスバーの表示メモ。

ちょっと急ぎで作成。。

html側。
jqueryとか使ってます。
■html.phpファイル

<head>
        <meta charset="utf-8" />
        <title>PHP Progress Sample</title>
        <link href="dist/css/bootstrap.css" rel="stylesheet">
</head>
<body>

        <div class="row">
                <div class="col-md-6 col-md-offset-3">
                        <h1>Progress Sample</h1>
                        <h2>ロード中</h2>
                        <div class="progress">
                                <div id="progress_elem" class="progress-bar progress-bar-striped active" role="progressbar" aria-valuenow="0" aria-valuemin="0" aria-valuemax="100" style="width: 0%;">0%</div>
                        </div>
                </div>
        </div>

        <script src="//code.jquery.com/jquery-1.11.0.min.js"></script>
        <script type="text/javascript">
                function updateBar(progress) {
                        var status = progress+"%";
                        $("#progress_elem").css({width: status}).text(status);

                }
        </script>
</body>

php側

■index.phpファイル

<?php

// htmlの出力
require('html.php');

echo str_pad(" ",4096)."<br />\n";

ob_end_flush();
ob_start('mb_output_handler');

$count=0;
$max_count = 15;

for($i=0; $i <= $max_count; $i++){
    $nCount = floor($count / $max_count * 100);
    echo '<script type="text/javascript">updateBar("' . $nCount . '")</script>';
    ob_flush();
    flush();

    $count++;
    sleep(1);
}

実際のサンプルはこちら

出力後に最下部にscriptタグを吐き出して無理矢理動かしている感じが
否めない。。

html開く⇒ajaxでバックエンドの処理をコール⇒進捗を定期的にjsが取りに行くっていう実装のほうが良いかも。

う~む。