csvでsum_byするようなやつ

例えばentry1に紐付けられているentry2とentry3のIDをsum_byするようなものを考えます。
まずは、csvのデータを取得する単純な方法です。基本形はこんな感じ。一行目のタイトル部分はスキップします。
$csv_path = 'test.csv';
$row = 0;
if (($handle = fopen($csv_path, "r")) !== FALSE) {
while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
$num = count($data);
if ($row > 0) {
for ($c=0; $c < $num; $c++) {
print $data[$c] . ",";
}
}
$row++;
print "<br>¥n";
}
fclose($handle);
}

結構ハマるのがエクセルなどからCSVを作成した時で、WindowsOSのエクセルはCRLFという改行コードで出力されるので問題ないのですが、MacOSXのエクセルからCSVを作成すると改行コードが、なんと、「CR」なのです。というわけで、fgetcsv関数が改行コードを読まないでスキップしてしまいますのでデータが壊れます。ここら辺りをまとめると、
CRの改行コードに対応していない
SJISだと、いわゆる5C問題にひっかかる
ということで、どのCSVにも対応するというマルチな仕様にするには、一手間かけて改行コードを調整する必要があります。典型的なのは改行コードを変換後にtemp.csvなどの一時ファイルを作成してやることです。
ereg_replace("\r\n|\r|\n","\n",mb_convert_encoding($file,"UTF-8","SJIS-win"));
(ereg_replaceはすでに非推奨かも。)

sum_byというかそんな感じでリレーションを取得するというのを考えます。なんかエライ長くなってしまいました。

<?php
#csvを読み込む
#対象のIDを検索してそのレコードを読み込む

$csvobject = new relation_csv();

# CSV基本パス設定
$csvobject->csvpath = 'relations.csv';
$csvobject->temp_csvpath = 'temp.csv';

# 文字コード変換
$csvobject->exchange_charset_csv();

# リレーションのパラメータ指定
$csvobject->asigned_column = 'entry2';
$csvobject->asigned_id = '1000';
$csvobject->relationed_column = 'entry1';

# リレーション集取を実行
$csvobject->get_relations_value();

# リレーションしているIDの値
var_dump($csvobject->temp_relations);

# プロパティーのデバック
//$csvobject->get_current_property(1);

class relation_csv {

/*

指定カラムのIDと同じレコードにある(関連する)他のカラムの値を取得します。
以下のようなデータベースCSVでは、
entry1,entry2,entry3
1,3,4
2,5,6
1,4,8
5,3,4

指定カラムentry1のID:1に関連するentry2カラムは、
1 => 3,4
が関連IDとなります。重複する場合は、マージされて常にユニークになります。

・1行目には各カラムのタイトル行を入れること。(カラム指定で使うから)
・CSVファイルは壊れていないことが前提。
・1カラムに対してもう一つのカラムデータとの関連のみ検出します。(複数カラムとの関係は指定できない)

(例)
$csvobject = new relation_csv();
$csvobject->csvpath = 'relations.csv';
$csvobject->temp_csvpath = 'temp.csv';
$csvobject->exchange_charset_csv();
$csvobject->get_current_property(1);
*/

#------
# path
#------
public $csvpath;
public $temp_csvpath = '/tmp/temp.csv';
public $pathinfo = array();

#------
# para
#------
public $asigned_column = 'entry1';
public $asigned_id = '42';
public $relationed_column = 'entry2';

#-----------------
# generated value
#-----------------
public $asigned_column_number;
public $relationed_column_number;
public $temp_relations = array();

#------------
# construct
#------------
function __construct() {

# path
$this->pathinfo = pathinfo(__FILE__);

$this->pathinfo['dirname'];
$this->pathinfo['basename'];
$this->pathinfo['extension'];
$this->pathinfo['filename'];

}//__construct()

#------------------
# exchange_charset
#------------------
function exchange_charset_csv() {
//print $this->csvpath;

if (is_file($this->csvpath)) {
$csvdata = file_get_contents($this->csvpath);
$csvdata = preg_replace("/¥r¥n¦¥r¦¥n/","¥n",mb_convert_encoding($csvdata,"UTF-8","SJIS-win"));
file_put_contents($this->temp_csvpath, $csvdata) or die('Error: Can not exchange charset on csv. ('.__FILE__.')');
}

}//exchange_charset_csv()

function get_relations_value() {
if (is_file($this->temp_csvpath)) {

# 指定カラムの検査
if ($this->asigned_column == $this->relationed_column) {
die('Error: Asigned_column name must different from Relationed column name. ('.__FILE__.')');
}

# カラム検索(何番目のカラムか算出)
$fp = fopen($this->temp_csvpath, "r");
$line = fgetcsv($fp, 0, ",");
fclose($fp);

foreach ($line as $key=>$val) {
if ($val == $this->asigned_column) {
$this->asigned_column_number = $key;
} elseif ($val == $this->relationed_column) {
$this->relationed_column_number = $key;
}
}
//print $this->asigned_column_number."<br>";

$fp = fopen($this->temp_csvpath, "r");
$row=0;
while (($data = fgetcsv($fp, 0, ",")) !== FALSE) {

if ($row > 0) {
$num = count($data);

//print $data[$this->asigned_column_number]." ";
//print $data[$this->relationed_column_number];
//print "<br>¥n";

if ($this->asigned_id == $data[$this->asigned_column_number]) {
array_push($this->temp_relations,$data[$this->relationed_column_number]);
}
}
$row++;
}
fclose($fp);

# 関連するIDを取得した。
$this->temp_relations = array_unique($this->temp_relations);

} else {
die('Error: Can not find csv temp file. ('.__FILE__.')');
}
}

#----------------
# Test function
#----------------
function get_test() {
print 'Hallo "class relation_csv"';
}//get_test()

#----------------------
# Get current Property
#----------------------
function get_current_property($cli=0) {

if ($cli ==1) {
$nn = "<br>¥n";
} else {
$nn = "¥n";
}

# csv path
print '$this->csvpath: '.$this->csvpath.$nn;
print '$this->temp_csvpath: '.$this->temp_csvpath.$nn;

# file path
print '$this->pathinfo[¥'dirname¥']: '.$this->pathinfo['dirname'].$nn;
print '$this->pathinfo[¥'basename¥']: '.$this->pathinfo['basename'].$nn;
print '$this->pathinfo[¥'extension¥']: '.$this->pathinfo['extension'].$nn;
print '$this->pathinfo[¥'filename¥']: '.$this->pathinfo['filename'].$nn;

# para
print '$this->asigned_column: '.$this->asigned_column.$nn;
print '$this->asigned_id: '.$this->asigned_id.$nn;
print '$this->relationed_column: '.$this->relationed_column.$nn;

# generated value
print '$this->asigned_column_number: '.$this->asigned_column_number.$nn;
print '$this->relationed_column_number: '.$this->relationed_column_number.$nn;
print '$this->temp_relations: ';
var_dump($this->temp_relations);

}//get_current_property()

}