follow us in feedly

Windows

WindowsのCakePHP3で発生したintlエラーを解決する

CakePHP3で開発するとintl拡張モジュールのエラーに出くわしますよね。
今回はWindowsらしい原因だったので、ちょっとハマりました。
ということで、解決した方法を書いていきます。

環境

  • Windows7
  • PHP 7.1.8
  • CakePHP 3.5.5

エラー内容

エラーはエクステンション関連の内容です。
なので、すぐに解決するだろうと思ってました。

Fatal error: You must enable the intl extension to use CakePHP.

intl拡張モジュールはあるし、php.iniにも設定してる

調べてみると解決方法として紹介されているのは、次の両方またはどちらかです。

  • intl拡張モジュールをインストールする
  • php.iniのextensionに設定する

でも、自分の環境ではどちらも問題ありませんでした。

C:¥php¥extにphp_intl.dllはあるし、
php.iniにも「extension=php_intl.dll」が設定されています。

Windows環境変数への設定が原因だった

モジュールも設定も問題ないのでハマりました。
Apacheの再起動とか、OSの再起動とか試してもやっぱりダメ。
そんななか、環境変数の設定をチェックしたところ。

ユーザー環境変数のほうにPHPのパスが書いてある。。。

すぐにシステム環境変数のほうにPHPのパスを追加して解決!
サイトが無事に表示されました。

まとめ

CakePHP3で見かけるintl拡張モジュールのエラー解決方法を紹介しました。
Windowsのシステム環境変数にPHPのパスを追加することで解決できます。
モジュールがないことやphp.iniの設定ばかりが原因ではないんですね。
Windows環境でCakePHP3を利用するときは注意してください。

MSYS2のpacmanで発生するGPGME errorの対応

Windowsでコマンドラインやターミナル環境を整えるためにMSYS2をインストールしました。
最近はWindowsで開発する機会もあったので作業環境を慣れた形にしたかったからです。
今回はMSYS2のパッケージ管理システムであるpacmanの初期設定に苦しむことに。
そのエラーと対応した内容をご紹介します。

環境

  • Windows 7
  • MSYS2 (mintty 2.8.1)
  • pacman 5.0.1

MSYS2のインストール

MSYS2のインストールはインストーラを実行して進めるだけなので簡単です。
詳しいインストール手順は、参考サイトを参照してください。

proxyの設定

proxy環境下で利用するので、C:/msys64/etc/profile.d/proxy.shを設定します。


export http_proxy=proxyserver.domain:port
export HTTP_PROXY=proxyserver.domain:port
export https_proxy=proxyserver.domain:port
export HTTPS_PROXY=proxyserver.domain:port
export no_proxy="localhost,127.0.0.1"
export NO_PROXY="localhost,127.0.0.1"

C:/msys64/etc/pacman.confを設定してcurlを使うようにします。


XferCommand = /usr/bin/curl -C - f %u > %o # コメントを外す

pacmanの初期設定時にエラーが発生する

MSYS2のインストールが完了したら、pacmanの設定をします。
リポジトリの更新や既存パッケージのアップデートです。
ここで下記エラーが発生しました。

エラー内容


$ pacman -Sy
:: パッケージデータベースの同期中...
エラー: GPGME error: データがありません
エラー: mingw32 の更新に失敗しました (無効または破損したデータベース (PGP 鍵))
エラー: GPGME error: データがありません
エラー: mingw64 の更新に失敗しました (無効または破損したデータベース (PGP 鍵))
エラー: GPGME error: データがありません
エラー: msys の更新に失敗しました (無効または破損したデータベース (PGP 鍵))
エラー: データベースの同期に失敗しました
エラー: 処理を始められませんでした (無効または破損したデータベース (PGP 鍵))

調べるために英語でも出力したので載せておきます。


$ pacman -Sy
:: Synchronizing package databases...
error: GPGME error: No data
error: failed to update mingw32 (invalid or corrupted database (PGP signature))
error: GPGME error: No data
error: failed to update mingw64 (invalid or corrupted database (PGP signature))
error: GPGME error: No data
error: failed to update msys (invalid or corrupted database (PGP signature))
error: failed to synchronize any databases
error: failed to init transaction (invalid or corrupted database (PGP signature))

解決方法がなかなか見つからない

上記エラーで調べるといろいろ情報は出てきます。
ただ、自分の場合は原因が違うようで、解決には至らずハマりました。
参考にした情報の一部を載せておきます。 (内容が同じようなものもあると思います)

curlではなくwgetを利用したら解決した

解決できたのは、wgetを使う設定にしてみたことでした。
proxyの設定時に有効にしていたcurlがダメだったようです。
proxy環境の都合なのか理由はわからないままですが。

とりあえず、C:/msys64/etc/pacman.confを下記のようにして無事に動作しました。
なんとなく設定を変えてみたら、あっさり解決することもありますよね。


#XferCommand = /usr/bin/curl -C - f %u > %o # コメントアウトする
XferCommand = /usr/bin/wget --passive-ftp -c -O %o %u # コメントを外す

まとめ

MSYS2のパッケージ管理システムであるpacmanのエラーと対応方法をご紹介しました。
pacmanがダウンロード時に利用するコマンドをcurlではなくwgetにすることで解決しました。
調べるといろいろな解決手段があるようなので、そのひとつとして参考なれば幸いです。

おまけ

MSYS2をちょっと快適に使えるかもしれない設定をします。
下記設定でシンボリックリンクの作成とWindowsの環境変数Pathの引き継ぎができるようになります。

C:/msys64/msys2.iniを編集します。


MSYS=winsymlinks:nativestrict # コメント外す シンボリックリンクの作成
#MSYS=error_start:mingw64/bin/qtcreator.exe|-debug|<process-id>
#CHERE_INVOKING=1
MSYS2_PATH_TYPE=inherit # コメント外す 環境変数引き継ぎ
MSYSTEM=MSYS

参考

Windows7のget-pip.pyで発生したエラーに対処する

前回記事にあるとおり、Windows上でPythonを使うことになりました。
ついでにPythonのパッケージ管理システムであるpipをインストールすることにしたのですが
ちょっとしたエラーが発生してすんなりとはいかなかったので対応方法をご紹介します。

環境

  • Windows 7
  • Python 3.6.3

get-pip.pyがエラーで動かない

ドキュメントに従ってインストールを試みるも下記エラーが発生。

エラー内容


Traceback (most recent call last):
  File "get-pip.py", line 20061, in <module>
    main()
  File "get-pip.py", line 194, in main
    bootstrap(tmpdir=tmpdir)
  File "get-pip.py", line 82, in bootstrap
    import pip
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 656, in _load_unlocked
  File "<frozen importlib._bootstrap>", line 626, in _load_backward_compatible
  File "C:\Users\77dogs\AppData\Local\Temp\tmpqicpv3hr\pip.zip\pip\__init__.py", line 26, in <module>
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 656, in _load_unlocked
  File "<frozen importlib._bootstrap>", line 626, in _load_backward_compatible
  File "C:\Users\77dogs\AppData\Local\Temp\tmpqicpv3hr\pip.zip\pip\utils\__init__.py", line 23, in <module>
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 656, in _load_unlocked
  File "<frozen importlib._bootstrap>", line 626, in _load_backward_compatible
  File "C:\Users\77dogs\AppData\Local\Temp\tmpqicpv3hr\pip.zip\pip\locations.py", line 88, in <module>
  File "ntpath.py", line 75, in join
TypeError: expected str, bytes or os.PathLike object, not NoneType

対応方法

C:\python\python36._pthを編集します。
下記のようにコメントをはずして、siteモジュールをインポートするように設定します。
該当設定の直上コメントにも、”Uncomment”と書いてありますね。


python36.zip
.

# Uncomment to run site.main() automatically
import site # ←コメントをはずす

再実行

再度実行します。無事にインストールが完了しました。
プロキシ環境下での実行なのでオプションを付けています。


$ python get-pip.py --proxy="[user:passwd@]proxy.server:port"
Collecting pip
  Downloading pip-9.0.1-py2.py3-none-any.whl (1.3MB)
Collecting setuptools
  Downloading setuptools-36.5.0-py2.py3-none-any.whl (478kB)
Collecting wheel
  Downloading wheel-0.30.0-py2.py3-none-any.whl (49kB)
Installing collected packages: pip, setuptools, wheel
Successfully installed pip-9.0.1 setuptools-36.5.0 wheel-0.30.0

まとめ

pipのインストール時に発生したエラーの対応方法をご紹介しました。
「import site」のコメントをはずすことで解消されます。
proxyオプションとあわせて参考なれば幸いです。

参考

pip — pip 9.0.1 documentation
python 3.6 embed cannot get pip · Issue #7 · pypa/get-pip

Windows版Python3でCSVをSQLiteに保存する

前回のWindows版PHPでのCSVパース問題を解決するためPythonを採用しました。
今回は、そのWindows + PythonでCSVを取り込む方法をご紹介します。
詳細な解説はほとんどなく、ほぼソースコードのみです。

環境

  • Windows 7
  • Python 3.6.3

ソースコード

CSVを読み込んでデータベースに保存します。
仕事で作ったものなので改変しています。

# -*- coding: utf-8 -*-

import os
import io
import sys
import csv
import sqlite3

# 標準出力の文字コードをUTF-8にする
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')

# ディレクトリを移動
os.chdir(r'C:\Users\77dogs\Sample')

# データベースに接続
conn = sqlite3.connect('db\contents.sqlite3')
c = conn.cursor()

# contentsテーブルのカラムを取得
sql = 'SELECT * FROM contents LIMIT 1'
c.execute(sql)
columns = []
for row in c.description:
    columns.append(row[0])

sql = 'INSERT INTO contents (%s) VALUES (%s)' \
        % (','.join(columns), ('?,' * len(columns)).rstrip(','))

# CSVの読み込み & 保存
with open('csv\data.csv', encoding='utf-8') as csvfile:
    reader = csv.reader(csvfile, delimiter=',', quotechar='"')
    next(reader)  # ヘッダ読み捨て

    for row in reader:
        c.execute(sql, tuple(row))  # SQLを実行
        conn.commit()  # commit()は必須

conn.close()

標準出力の文字コードを変更する

MSYS2にprint()で出力したときに文字化けしたのでその対策。
sys.stdoutのデフォルトの文字コードはCP932なのでUTF-8に変更。
ちなみに、上記ソースコードにはprint()はありません。

print(sys.stdout.encoding)  # cp932
sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding='utf-8')
print(sys.stdout.encoding)  # utf-8

raw文字列によってエスケープシーケンスを無効にする

エスケープシーケンス(\n, \t など)として解釈してほしくない場合の対策。
下記の場合は、「\U」があるのでraw文字列でないとエラーになる。

# SyntaxError: (unicode error) 'unicodeescape' codec can't decode bytes in position 2-3: truncated \UXXXXXXXX escape
os.chdir('C:\Users\77dogs\Sample')

# raw文字列(r'文字列')だとエスケープシーケンスを無効化
os.chdir(r'C:\Users\77dogs\Sample')

まとめ

Windows + Python3を使って無事にCSVの取り込むができました。
情報もたくさんあるので、多少のつまづきはあったものの簡単に実装できました。
ファイルパスにバックスラッシュを使う場合はエスケープシーケンスに注意です。
はじめてのPython成果物ですが参考になれば幸いです。

参考

sys.stdout のエンコードを変更する in Python3.0
raw文字列 – 文字列 – Python入門
エスケープシーケンス – 文字列 – Python入門
Pythonでsqlite

Windows版PHPでCSVが正しくパースされない問題に悩んだ

仕事でちょっとした多言語サイトを開発することになったわけですが
掲載情報をCSVで取り込むときに正しくパースされない問題に悩まされました。
ということで、解決(?)するまでの経緯を書いていきます。

環境

Windows7
PHP 7.1.8
SQLite 3.20.0

Windows7 + PHPでマルチバイト文字のCSVのパースができなかった

今回、開発するサイトは多言語のサイトです。
日本語に加えて英語、韓国語、中国語(繁体字・簡体字)も扱います。

各言語のCSVをPHPのSplFileObjectで読み込もうとするも
日本語、韓国語、中国語といったマルチバイト文字の言語が適切にパースされませんでした。
文字コードはすべてUTF-8です。

文字エンコードをしてみる

UTF-8のまま読みたかったが仕方がないので、下記のとおりにエンコードすることに。
すると、いい感じにパースされたので、「解決!」と思ったのだけど。。。

  • 日本語→CP932
  • 韓国語→CP949
  • 繁体字→CP950
  • 簡体字→CP936

エンコードできない文字がある

いい感じだったのは日本語、韓国語まで。
繁体字になってエンコードできない文字(?になってる)があることが判明。
簡体字も繁体字ほどではないにしろ同様で、よくよくみると韓国語もまれにあるという状況でした。

setlocaleも試してみる

文字化けするのなら、UTF-8でなんとかするしかないかと考えて
setlocale()をするもパース位置が変わる程度で解決には至らず。

ちなみに、Windowsでのsetlocale()はセットの仕方に注意。

# これだとセットできない
setlocale(LC_ALL, 'ja_JP'):

# これだとセットできる
setlocale(LC_ALL, 'Japanese_Japan');
setlocale(LC_ALL, 'Japanese_Japan.932');
setlocale(LC_ALL, 'ja-JP');

他の環境での動きを見てみる

以下の3つの環境でどうなるかを見てみた。

  • CendOS6 + PHP5.3
  • Windows7 + Python3
  • Windows PowerShell

結果としては、上記の環境ではUTF-8のまま問題なくパースできました。
ということで、Windows版PHPがダメらしいということがわかったのです。

Windows7 + Python3でやることにした

時間も限られているので、PHPでの解決は諦めることにして
Windows7 + Python3でCSVを取り込むことにしました。

理由としては、

  • 今回は諸事情によりWindows環境でやるしかないこと
  • PowerShellでもいいのだけど、Pythonを使ってみたかったからです。

ここにはPythonでの詳細は書きませんが無事に取り込めました。

まとめ

Windows7 + PHPでの開発で遭遇したCSVのパース問題をご紹介しました。

  • CSVがマルチバイト文字の言語だと正しくパースされなかった
  • 各言語をUTF-8からエンコードするとパースはされたが一部文字化けした
  • setlocale()するも期待した結果は得られなかった

結局、Windows版PHPがダメだと判断して、Pythonを使うことで解決しました。
Windows + PHPでの開発をお考えの方はご注意ください。