2011年05月02日

2010年10月14日

バイナリセーフではない関数

これでいいの?

ereg(), ereg_replace(), eregi(), eregi_replace(),
split(), spliti(),
include(), include_once(), require(), require_once()
fopen(), file_get_contents(), readfile(), basename()

よくわからない。
file_get_contents()はファイル名がバイナリセーフではないということ?ファイルの内容が??

で、バイナリセーフってなんだっけ?
posted by ほえ at 15:40| Comment(0) | TrackBack(0) | PHP | このブログの読者になる | 更新情報をチェックする

2010年08月17日

Zの次はAAな件


$c = 'Z';
$c++;
echo $c; -> 'AA'

になる。

でもこれは違う結果に

$c = 'Z';
$c += 1;
echo $c; -> 1

なぜ1?
posted by ほえ at 09:56| Comment(0) | TrackBack(0) | PHP | このブログの読者になる | 更新情報をチェックする

2010年07月06日

preg_splitで、文字列を分割すると値が空の要素ができてしまうのです。

preg_splitで、文字列を分割すると値が空の要素ができてしまうのです。

C:\>php -r "var_dump(preg_split('//', 'string'));"
array(8) {
[0]=>
string(0) ""
[1]=>
string(1) "s"
[2]=>
string(1) "t"
[3]=>
string(1) "r"
[4]=>
string(1) "i"
[5]=>
string(1) "n"
[6]=>
string(1) "g"
[7]=>
string(0) ""
}

PREG_SPLIT_NO_EMPTYを指定すれば、空の要素は取り除いてくれます。

C:\>php -r "var_dump(preg_split('//', 'string', null, PREG_SPLIT_NO_EMPTY));"
array(6) {
[0]=>
string(1) "s"
[1]=>
string(1) "t"
[2]=>
string(1) "r"
[3]=>
string(1) "i"
[4]=>
string(1) "n"
[5]=>
string(1) "g"
}

3つ目の引数は、最大の分割数ですがnullを指定しておけば最大数の指定なしになります。0でも-1でも良いようですが、マニュアルには

制限を指定せずに flags パラメータを指定したい場合などに null を使用します。

とあります。

対象の文字列が空という場合の方が多いかもしれませんね。

C:\>php -r "var_dump(preg_split('/ /', ''));"
array(1) {
[0]=>
string(0) ""
}



C:\>php -r "var_dump(preg_split('/ /', '', null, PREG_SPLIT_NO_EMPTY));"
array(0) {
}

となる。
知らなかったので。
posted by ほえ at 16:27| Comment(0) | TrackBack(0) | PHP | このブログの読者になる | 更新情報をチェックする

2010年03月17日

配列をマージするのにarray_merge()と+とどっちを使ったらいいのかな?の件

2つの配列をマージするのに、array_merge()と配列演算子の+とどちらを使ったらよいのかよくわからなくなるのでメモしておきます。

array_merge()関数

配列をマージします。

$arr1 = array(1, 2, 3);
$arr2 = array(4, 5, 6);
$result = array_merge($arr1, $arr2);

Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
[5] => 6
)


値が同じでも関係ない。

$arr1 = array(1, 2, 3);
$arr2 = array(1, 2, 3);
$result = array_merge($arr1, $arr2);

Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 1
[4] => 2
[5] => 3
)


同じキーは上書きされる。後の配列で上書きされる。

$arr1 = array('a' => 1, 'b' => 2, 'c' => 3);
$arr2 = array('b' => 4, 'c' => 5, 'd' => 6);
$result = array_merge($arr1, $arr2);

Array
(
[a] => 1
[b] => 4
[c] => 5
[d] => 6
)


数値添字は振り直される。

$arr1 = array(1 => 1, 3 => 2, 5 => 3);
$arr2 = array(7 => 4, 9 => 5, 11 => 6);
$result = array_merge($arr1, $arr2);

Array
(
[0] => 1
[1] => 2
[2] => 3
[3] => 4
[4] => 5
[5] => 6
)


キーと数値添字が混ざっていても、数値添字は振り直される。

$arr1 = array(1 => 1, 'a' => 2, 5 => 3);
$arr2 = array('b' => 4, 9 => 5, 'c' => 6);
$result = array_merge($arr1, $arr2);

Array
(
[0] => 1
[a] => 2
[1] => 3
[b] => 4
[2] => 5
[c] => 6
)




配列演算子+

左にないキーを追加します。以下の場合数値添字0,1,2は左にあるので追加されません。

$arr1 = array(1, 2, 3);
$arr2 = array(4, 5, 6);
$result = $arr1 + $arr2;

Array
(
[0] => 1
[1] => 2
[2] => 3
)



値が同じでも関係ない。

$arr1 = array(1, 2, 3);
$arr2 = array(1, 2, 3);
$result = $arr1 + $arr2;

Array
(
[0] => 1
[1] => 2
[2] => 3
)


同じキーは上書きされないし、追加もされない。

$arr1 = array('a' => 1, 'b' => 2, 'c' => 3);
$arr2 = array('b' => 4, 'c' => 5, 'd' => 6);
$result = $arr1 + $arr2;

Array
(
[a] => 1
[b] => 2
[c] => 3
[d] => 6
)



数値添字でも左にければ追加される。

$arr1 = array(1 => 1, 3 => 2, 5 => 3);
$arr2 = array(7 => 4, 9 => 5, 11 => 6);
$result = $arr1 + $arr2;

Array
(
[1] => 1
[3] => 2
[5] => 3
[7] => 4
[9] => 5
[11] => 6
)


キーと数値添字が混ざっていても、左になければ追加される。

$arr1 = array(1 => 1, 'a' => 2, 5 => 3);
$arr2 = array('b' => 4, 9 => 5, 'c' => 6);
$result = $arr1 + $arr2;

Array
(
[1] => 1
[a] => 2
[5] => 3
[b] => 4
[9] => 5
[c] => 6
)






ちなみに。

これは?

$arr1 = array('001' => 1, 'a' => 2, '005' => 3);
$arr2 = array('b' => 4, '009' => 5, 'c' => 6);
$result = array_merge($arr1, $arr2);

Array
(
[001] => 1
[a] => 2
[005] => 3
[b] => 4
[009] => 5
[c] => 6
)



$arr1 = array('001' => 1, 'a' => 2, '005' => 3);
$arr2 = array('b' => 4, '009' => 5, 'c' => 6);
$result = $arr1 + $arr2;

Array
(
[001] => 1
[a] => 2
[005] => 3
[b] => 4
[009] => 5
[c] => 6
)



これは?

$arr1 = array(1.0 => 1, 'a' => 2, '005' => 3);
$arr2 = array('1' => 4, '009' => 5, 'c' => 6);
$result = array_merge($arr1, $arr2);

Array
(
[0] => 1
[a] => 2
[005] => 3
[1] => 4
[009] => 5
[c] => 6
)



$arr1 = array(1.0 => 1, 'a' => 2, '005' => 3);
$arr2 = array('1' => 4, '009' => 5, 'c' => 6);
$result = $arr1 + $arr2;

Array
(
[1] => 1
[a] => 2
[005] => 3
[009] => 5
[c] => 6
)


同じキーだったら上書きしないで、数値添字だったら振りなおして追加してくれる!っていうのはないのかしら?
posted by ほえ at 11:04| Comment(0) | TrackBack(0) | PHP | このブログの読者になる | 更新情報をチェックする

2009年12月16日

バージョン上げたらPostgreSQLに接続できなくなったでござる!

とあるWindowsXPのPHPを5.0.4から5.2.11にバージョンアップしました。
面倒くさいのでzip版を解凍して置いて、php.iniを直したら、phpでPostgreSQLに接続できなくなってしまいました。phpinfo()で見てもpgsqlの項目が出てきません。
PostgreSQLのバージョンは8.1.1でした。
Apacheのログを見ると

PHP Warning: PHP Startup: Unable to load dynamic library 'C:\\PHP\\ext\\php_pgsql.dll' - \x8ew\x92\xe8\x82\xb3\x82\xea\x82\xbd\x83v\x83\x8d\x83V\x81[\x83W\x83\x83\x82\xaa\x8c\xa9\x82\xc2\x82\xa9\x82\xe8\x82\xdc\x82\xb9\x82\xf1\x81B\r\n in Unknown on line 0

とエラーが出ていました。でも意味不明です。

いろいろ具具って見たらどこかのページにlibeay32.dllやssleay32.dllのバージョンが古いのかもみたいな事がでていたので(PHPのマニュアルのコメント欄だったかも!)、ふとPostgreSQLのbinのフォルダを見たらlibeay32.dllがありました。
Windowsの環境変数PATHの最後に…;C:\PHP\と書いていたのですが、これをPATHの先頭にもっていって、PCを再起動したらApacheのエラーログにエラーが出なくなって、PHPから接続できるようになっていました。

めでたしめでたし。

えらい時間かかってしまった。こんなん、わかるかい!!
posted by ほえ at 16:24| Comment(0) | TrackBack(0) | PHP | このブログの読者になる | 更新情報をチェックする

2009年08月14日

キャッシュ難しい(メモ)


session_start();
header('Cache-Control: must-revalidate');
header('Expires: Fri, 01 Jan 1999 00:00:00 GMT');
header('Pragma: ');

とかすると、

レスポンスヘッダ
Date Fri, 14 Aug 2009 02:10:33 GMT
Server Apache/2.0.58 (Win32) DAV/2 mod_python/3.3.1 Python/2.5.1 PHP/5.2.9-2 SVN/1.4.5
X-Powered-By PHP/5.2.9-2
Expires Fri, 01 Jan 1999 00:00:00 GMT
Cache-Control must-revalidate
Keep-Alive timeout=15, max=100
Connection Keep-Alive
Transfer-Encoding chunked
Content-Type text/html; charset=UTF-8
Content-Language ja

になるんだけど…。
posted by ほえ at 11:13| Comment(0) | TrackBack(0) | PHP | このブログの読者になる | 更新情報をチェックする

2009年07月24日

@をつけるのはの件の続き



$a = @$b;

みたいに@をつける理由がようやっとわかりました。$bが定義されていない時エラーにならないようになんですね!って思ったんだけど違う??

エラーじゃなくてワーニングでした。
そして、php.iniでerror_reportingがE_ALL & ~E_NOTICEだとワーニングが表示されません。
php.iniで

error_reporting=E_ALLに

変更するか、コード中で

error_reporting(E_ALL);

で変更すると、

PHP Notice: Undefined variable: b in Command line code on line 1

Notice: Undefined variable: b in Command line code on line 1

といわれます。
posted by ほえ at 10:40| Comment(0) | TrackBack(0) | PHP | このブログの読者になる | 更新情報をチェックする

2009年07月13日

配列のキーに.(ピリオド)を入れてみた件


<?php
$a = array(aaa.bbb => 100);
print_r($a);

てしたら、

Array
(
[aaabbb] => 100
)

こんなになっちゃった。
なんで?

まぁ、こうなんですけど。

<?php
$a = array('aaa.bbb' => 100);
print_r($a);

=>

Array
(
[aaa.bbb] => 100
)

posted by ほえ at 17:31| Comment(0) | TrackBack(0) | PHP | このブログの読者になる | 更新情報をチェックする

2009年05月21日

SimpleTestその1

SimpleTestをする事にしました。

http://downloads.sourceforge.net/simpletest/simpletest_1.0.1.tar.gz
ダウンロードして、php.iniのinclude_pathの通っているところに置いた。
c:/php/includeがinclude_pathにあったので、

c:/php/include/simpletest/autorun.php

になるように。


まずはこれから。
http://www.simpletest.org/en/start-testing.html

ディレクトリはこんな

[htdocs]/test/simpletest/classes
/test

http://localhost/test/simpletest/test/log_test.php
でブラウザからアクセスできるように。urlがtestだらけだけど。

ログクラス(classes/log.php)のテストをする。
test/log_test.php

<?php
require_once('simpletest/autorun.php');
require_once(dirname(__FILE__).DIRECTORY_SEPARATOR.'../classes/log.php');

class TestOfLogging extends UnitTestCase {
}
?>

require_once('../classes/log.php');
だと後でエラーになっちゃったので、このように。


テストケースはSipleTestCaseクラスを継承する。

テストケースを実行すると、"test"で始まるメソッドを探して実行する。

テストの内容を追加する。
test/log_test.php

<?php
require_once('simpletest/autorun.php');
require_once(dirname(__FILE__).DIRECTORY_SEPARATOR.'../classes/log.php');

class TestOfLogging extends UnitTestCase {
function testLogCreatesNewFileOnFirstMessage() {
@unlink('c:/tmp/test.log');
$log = new Log('c:/tmp/test.log');
$this->assertFalse(file_exists('c:/tmp/test.log'));
$log->message('Should write this to a file');
$this->assertTrue(file_exists('c:/tmp/test.log'));
}
}
?>


ブラウザでアクセスして赤は失敗、緑は成功。

Fatal error: Failed opening required '../classes/log.php' (include_path='') in /home/marcus/projects/lastcraft/tutorial_tests/Log/tests/log_test.php on line 7
だったら、classes/log.phpが存在しない。

classes/Log.phpを作成する。

<?php
class Log {
function Log($file_path) {
}

function message() {
}
}
?>

ブラウザでアクセスする。赤で失敗。

Logクラスのmessage()メソッドを記述する。
classes/Log.php

<?php
class Log {
function Log($file_path) {
}

function message($message) {
$fp = fopen('c:/tmp/test.log', 'w');
if ($fp === false) {
echo '開きません!';
exit;
}

if (fwrite($fp, $message) === false) {
echo '書き込めません!';
exit;
}
fclose($fp);
}
}

ブラウザでアクセスする。緑になって成功。

次は、テストスイーツを作成してみる。
test/all_tests.php

<?php
require_once('simpletest/autorun.php');

class AllTests extends TestSuite {
function AllTests() {
$this->TestSuite('All tests');
$this->addFile(dirname(__FILE__).DIRECTORY_SEPARATOR.'log_test.php');
}
}

$this->addFile('log_test.php');だと見つからない!ってエラーになっちゃうのでこのように

ブラウザでアクセスする。緑になって成功。

次はモックオブジェクトを使ってみる。

SessionPoolクラスがこんな時、
classes/session_pool.php

<?php
class SessionPool {
function __construct(&$log)
{
$this->_log = $log;
}

function logIn($username)
{
$this->_log->message("User $username logged in.");
}
}

コンストラクタのパラメータで渡されたオブジェクト$logを使っているわけです。

テストはこちら。
session_pool_test.php

<?php
require_once('simpletest/autorun.php');
require_once(dirname(__FILE__).DIRECTORY_SEPARATOR.'../classes/log.php');
require_once(dirname(__FILE__).DIRECTORY_SEPARATOR.'../classes/session_pool.php');

Mock::generate('Log');

class TestOfSessionLogging extends UnitTestCase {

function testLoggingInIsLogged() {
$log = new MockLog();
//「$log->message('User fred logged in.')が1回呼ばる事を期待する」という機能を仕込む
$log->expectOnce('message', array('User fred logged in.'));
$session_pool = new SessionPool($log);
$session_pool->logIn('fred');
//$session_poolのlogInメソッドで、$log->message('User fred logged in.')を呼んでいるはず!
//もし呼んでいなければエラー!!
}
}


Mock::generate('Log');で、MockLogクラスが使えるようになるのです。
最初、モックオブジェクト使うからLogクラスいらないじゃんって、classes/log.phpをrequireしてなくて、「MockLogクラスなんて知らない!」というエラーが出てはまった。
そういうことかぁ。

ブラウザでテストしましたが、コマンドプロンプトでもテストできます。

C:\Program Files\Apache Group\Apache2\htdocs\test\simpletest\test>php session_pool_test.php
session_pool_test.php
OK
Test cases run: 1/1, Passes: 2, Failures: 0, Exceptions: 0

C:\Program Files\Apache Group\Apache2\htdocs\test\simpletest\test>

こんな感じ。
posted by ほえ at 18:28| Comment(0) | TrackBack(0) | PHP | このブログの読者になる | 更新情報をチェックする

2009年04月06日

PHPExcelのバージョンをあげたらの件

1.6.4から1.6.6にしたら、今まで'腐ってやがる'といって読み込めなかったxlsファイルが読み込めるようになった。
1.6.4じゃバージョンが早すぎたんだ!
posted by ほえ at 21:47| Comment(0) | TrackBack(0) | PHP | このブログの読者になる | 更新情報をチェックする

2008年12月24日

PHP OpenIDで…というよりcURLで…というよりPHPで。

PHP OpenIDをwindowsで試してみました。バージョンは2.1.2。
PHPは5.2.3。

\examples\consumerを試して見ましたが、livedoorのOpenIDではそのままでは認証できませんでした。

いろいろなサイトを参考にして、Yahoo!とかlivedoorとかはてなとかで試してみたら、はてなはこんなにしたら認証できた!



<?
if (!strncmp(PHP_OS, 'WIN', 3)) {
define('Auth_OpenID_RAND_SOURCE', NULL);
}
define('Auth_Yadis_CURL_OVERRIDE', '1');

require_once "common.php";

でもはてなだけ。livedoorはダメ。Yahoo!もダメ。

なんだろう?

結局

define('Auth_Yadis_CURL_OVERRIDE', '1');

は関係なかった。

これはPHPでcURLが使えない場合こうしたら…という事だったのですが、はてなには無関係でした。あらら?

PHPのcURL関数のマニュアル(PHPのその他のサービスの下ね)をみると、「windowsの場合はlibeay32.dllが…」のようなめんどくさそうな事が書いてあったので、使わない方法というのを試してみたわけですが、関係ありませんでした。あと、マニュアルに書いてあることは別に面倒くさいことではなくて、他にどこかからライブラリを持ってくる必要はないですよ!という事が言いたかったようです。libeay32.dllとssleay32.dllはc:\phpに元々入っているのです。


ではcURL関数を使えるようにすれば他のOpenIDも?と思ってマニュアルにあるように

  • libeay32.dll、ssleay32.dllをPATHの通った所に置く

  • php.iniの;extension=php_openssl.dllの先頭のコロンを削除する


とするわけです。

php.iniを修正して、apacheの再起動をしたですよ。そうすればphpinfo()で、cURLの項目が出るはずです。が、出てきませんでした。

c:\phpにPATHは通っているしなぁと思ってふと

which libeay32.dll

を実行したら(cygwinて便利ですね!)、別にインストールしていた

C:\ruby\bin\libeay32.dll

が出てきてしまいました!

これだ!と思って、PATHの順番を

C:\ruby\bin;.....C:\php;...

から

C:\php;...C:\ruby\bin;.....

に入替えて、PCを再起動して、phpinfo()でどうだ!と思ったら、まだ出てきませんでした。一体これは???


で、ここにいたってapacheのerror.logをもう一度見てみることにしたら、こんな事に!!

PHP Warning: PHP Startup: curl: Unable to initialize module\nModule compiled with module API=20050922, debug=0, thread-safety=1\nPHP compiled with module API=20060613, debug=0, thread-safety=1\nThese options need to match\n in Unknown on line 0

実は他にエラーが出ている所があって、それは別にいいやって放っておいたのがあったのです。こんなの

[Wed Dec 24 15:18:45 2008] [error] python_init: Python version mismatch, expected '2.5', found '2.5.1'.

で、cUrlのワーニングは先頭に日時とかが出ないので、このエラーの続きだと思ってしまっていて無視していたわけです。あぁ。


それで、これは何だという事になるのですが、c:\phpのフォルダを見ると、他のdllと全然日付が違うのです。どうやら古いバージョンのphpに上書きしてインストールしたらこうなった??昔の事だから覚えていない…。PHPの今使っているバージョンのzipをダウンロードして(ここから)、libeay32.dllとssleay32.dllとext\php_curl.dll、ext\php_openssl.dllを解凍してc:\phpとc:\php\extに上書きしてapacheを再起動してphpinfo()にcURLの項目が出るようになりました。

curl
+------------------+------------------------------------------+
| cURL support | enabled |
| cURL Information | libcurl/7.16.0 OpenSSL/0.9.8e zlib/1.2.3 |
+------------------+------------------------------------------+

でも、相変わらずlivedoorとYahoo!は認証してくれませんでした。


続く…。
posted by ほえ at 15:38| Comment(0) | TrackBack(0) | PHP | このブログの読者になる | 更新情報をチェックする

2008年10月28日

array_diff_key()にハマった件

array_key_diff()にやられました。

$arr1 = array('hoe1' => 1, 'hoe2' => 2);
$arr2 = array('hoe2' => 2, 'hoe3' => 3);

の時、

print_r(array_diff_key($arr1, $arr2)); //-> array([hoe1] => 1, [hoe3] => 3)

だと思ったら、

array([hoe1] => 1)

しか出てこなかった…。マニュアルに書いてはあるんだけど…。わかんないよ!diffっていうから両方の違いだと思うじゃん!!
こうするとよいみたい。

print_r(array_diff_key($arr1, $arr2) + array_diff_key($arr2, $arr1)); //-> array([hoe1] => 1, [hoe3] => 3)


array_diff()も同じか!
posted by ほえ at 19:29| Comment(0) | TrackBack(0) | PHP | このブログの読者になる | 更新情報をチェックする

2008年08月08日

いまさらながら、null,is_null(),'',isset(),==,===


<?php
class Hoe {
}

$a = new Hoe();

var_dump($a->p == null); //true
var_dump($a->p === null); //true
var_dump(is_null($a->p)); //true
var_dump($a->p == ''); //true

var_dump($a->p === ''); //false
var_dump(isset($a->p)); //false

ですっ。
posted by ほえ at 14:08| Comment(0) | TrackBack(0) | PHP | このブログの読者になる | 更新情報をチェックする

2008年08月06日

XMLのを出力しようとして困った件

phpでこんな感じにしたら、エラーになった。

<?php
echo 'test!';
?>
<?xml version="1.0" encoding="UTF-8"?>
<xml>
...
</xml>

「<?xml」の「<?」が気に入らないらしい。
こりゃ困ったと思っていたら、こうするといいらしいいいぃぃぃ!

<?php
echo 'test!';
?>
<<??>?xml version="1.0" encoding="UTF-8"?>
<xml>
...
</xml>

やほーい。


マニュアルのコメント欄にに書いてあった!
posted by ほえ at 15:53| Comment(0) | TrackBack(0) | PHP | このブログの読者になる | 更新情報をチェックする

2008年08月01日

@をつけるのはの件


$a = @$b;

みたいに@をつける理由がようやっとわかりました。
$bが定義されていない時エラーにならないようになんですね!
って思ったんだけど違う??
posted by ほえ at 22:31| Comment(0) | TrackBack(1) | PHP | このブログの読者になる | 更新情報をチェックする

2008年05月22日

echoの件

echoについて知らなかったので書いておきます。
echo('a');
って書くことが多いけど、
echo 'a';
って書ける事はしってました。でも、
echo 'a', 'b';
って書ける事は知りませんでした!さらに
echo('a', 'b');
って書けない事を知らなかったのは当然か。
posted by ほえ at 15:13| Comment(0) | TrackBack(0) | PHP | このブログの読者になる | 更新情報をチェックする

2008年04月07日

ついでにクラス定数の件

クラス定数です。

class Hoe {
const CLASS_CONST = 'hoe';
}

前のクラス変数についてよくわかってない件とほぼ同じです。

オーバーライドしていないメソッドから、クラス定数を参照すると、親クラスのクラス定数を参照してしまいます。

動的なクラス参照から参照する?にはget_class_const()なんていうのが無いので、

$class_name = 'Hoe';
echo const($class_name.'::CLASS_CONST');

とconst()関数を使うようです。
posted by ほえ at 16:57| Comment(0) | TrackBack(0) | PHP | このブログの読者になる | 更新情報をチェックする

クラス変数についてよくわかってない件

クラス変数です。

class Hoe {
public static $class_var = 'Hoe';

public function get_self_class_var()
{
return self::$class_var; // -> 'Hoe'
}

//オーバーライド禁止
final public function get_self_class_var_no_extends()
{
return self::$class_var;
}
}

class Hoehoe extends Hoe {
//オーバーライド
public static $class_var = 'Hoehoe';

//オーバーライド
public function get_self_class_var()
{
return self::$class_var;
}

public function call_parent_get_self_class_var()
{
//親クラスのメソッドを呼ぶ
return parent::get_self_class_var();
}
}

の時、こんなになります。

echo Hoe::$class_var; // -> 'Hoe'
echo Hoehoe::$class_var; // -> 'Hoehoe'

$var_hoe = new Hoe();
$var_hoehoe = new Hoehoe();

echo $var_hoe->get_self_class_var(); // -> 'Hoe'
echo $var_hoehoe->get_self_class_var(); // -> 'Hoehoe'


これは、

echo $var_hoehoe->call_parent_get_self_class_var(); // -> 'Hoe'

親のメソッドの中で、self::$class_varを参照しているので、'Hoe'になります。

次のがわかってませんでした。

echo $var_hoehoe->get_self_class_var_no_extends(); // -> 'Hoe'

親クラスのメソッドをオーバーライドしていないと、親クラスのクラス変数を参照してしまうのですね!!
なんとなく、継承してるんだから子供のクラスのクラス変数を参照しそうな気がしてします。
気をつけないと。


これについて5.3.0から「遅延静的束縛(Late Static Binding = LSB)」というのが使えるようになるそうです。
ほーう。


マニュアルの「staticキーワード」のところに「PHP 5.3.0 以降では、変数を用いてクラスを参照することも可能です。」とあるのは

$class_name = 'Hoehoe';
echo $class_name::$class_var; // <- 'Hoehoe'

とか

echo $var_hoehoe::$class_var; // <- 'Hoehoe'

とできるという事です。
5.3.0より前だとエラーになってしまうので、こんなにしたりします。

$vars = get_class_vars('Hoehoe');
echo $vars['class_var'];

ちょいと面倒ですな。

posted by ほえ at 16:32| Comment(0) | TrackBack(0) | PHP | このブログの読者になる | 更新情報をチェックする

2008年02月29日

fgetcsv()で日本語が入っているフィールドが正しく読み込まれない件その2

以前こんなのを書いていました。
fgetcsv()で日本語が入っているフィールドが正しく読み込まれない件
で、マニュアルには
注意: この関数はロケール設定を考慮します。もし LANG が例えば en_US.UTF-8 の場合、 ファイル中の 1 バイトエンコーディングは間違って読み込まれます。
とあります。
Webを検索すると、ロケールを設定すれば日本語も読めるようになるという記述も見られますが、WindowsでUTF-8のcsvファイルは読めないようです。

Windowsなのでロケール設定はこんなにして書きます。
setlocale(LC_ALL, "japanese_japan");

で、どうなったか確認してみると、
setlocale(LC_ALL, "0");
-> Japanese_Japan.932

最後の「932」はコードページで「Shift_JIS」になります。
http://ja.wikipedia.org/wiki/Microsoft%E3%82%B3%E3%83%BC%E3%83%89%E3%83%9A%E3%83%BC%E3%82%B8932
じゃあこれをUTF-8にしちゃえ!と思って、
setlocale(LC_ALL, "japanese_japan.UTF-8");

とか、
setlocale(LC_ALL, "japanese_japan.65001");

とかしても、
setlocale(LC_ALL, "0");
-> LC_COLLATE=C;
LC_CTYPE=Japanese_Japan.932;
LC_MONETARY=C;
LC_NUMERIC=C;
LC_TIME=C"
と、LC_CTYPEは932のままです。
fget_csvに影響があるのはLC_CTYPEのようなのでこれではダメですね。
マニュアルのsetlocaleから、
LC_CTYPE 文字の分類と変換。たとえば strtoupper()


ちなみに、一度オランダ語に設定してから、上記を実行すると、

setlocale(LC_ALL, "nld_nld");
setlocale(LC_ALL, "japanese_japan.65001");
setlocale(LC_ALL, "0");
-> LC_COLLATE=Japanese_Japan.65001;
LC_CTYPE=Dutch_Netherlands.1252;
LC_MONETARY=Japanese_Japan.65001;
LC_NUMERIC=Japanese_Japan.65001;
LC_TIME=Japanese_Japan.65001

と、LC_CTYPEだけオランダ語のままという、妙な事になります。
posted by ほえ at 12:49| Comment(0) | TrackBack(0) | PHP | このブログの読者になる | 更新情報をチェックする

広告


この広告は60日以上更新がないブログに表示がされております。

以下のいずれかの方法で非表示にすることが可能です。

・記事の投稿、編集をおこなう
・マイブログの【設定】 > 【広告設定】 より、「60日間更新が無い場合」 の 「広告を表示しない」にチェックを入れて保存する。


×

この広告は1年以上新しい記事の投稿がないブログに表示されております。