如何从 PHP 中的多维数组输出 CSV 文件中缺失属性的空格
How to output blank spaces for missing attributes in CSV file from multidimensional array in PHP
我在输出空格和确保我的所有 CSV 数据都输出到正确位置时遇到了一些问题,我想知道我该如何做到这一点。
我正在尝试将 LDAP 服务器搜索的输出格式化为 CSV 格式,但问题是某些条目的属性顺序不正确,或者某些条目的属性完全缺失。
这是一些数据的例子
Array
(
[0] => Array
(
[dc=example,dc=com] => Array
(
[o] => example.com
[objectclass] => Array
(
[0] => simpleSecurityObject
[1] => dcObject
[2] => organization
)
[dc] => example
)
)
[1] => Array
(
[uid=newton,dc=example,dc=com] => Array
(
[sn] => Newton
[objectclass] => Array
(
[0] => simpleSecurityObject
[1] => dcObject
[2] => organization
)
[uid] => Newton
[mail] => newton@ldap.forumsys.com
[cn] => Isaac Newton
)
)
)
请注意,在第一个 ([0]) 数组中,我有一个名为“o”和“dc”的条目,而在第二个数组中,我没有。
所以基本上,我想输出这个:
distinguishedname,o,objectclass,dc,sn,uid,mail,cn
dc=example,dc=com,example.com,{simpleSecurityObject,dcObject,organization},example, , , ,
uid=newton,dc=example,dc=com, ,{simpleSecurityObject,dcObject,organization}, , ,Newton,newton@ldap.forumsys.com,Isaac Newton
我不太确定如何做两件事:
- 确保将所有缺失的属性替换为“”,使其显示为空
- 确保将正确的属性放在正确的位置。例如,“o”可能是一个条目中的第 3 个属性,但它可能是另一个条目中的第 6 个属性。如何确保我的 CSV 数据按以下顺序排列:
distinguishedname,o,objectclass,dc,sn,uid,mail,cn
这是一些以 CSV 格式输出所有数据的代码,但我不确定如何制作空字段并使它们对齐。输出只是所有数据的打印。
<?php
$movies = array(
"dc=example,dc=com" => array(
"o" => "example.com",
"objectclass" => array("simpleSecurityObject", "dcObject", "organization"),
"dc" => "example"),
"uid=newton,dc=example,dc=com" => array(
"sn" => "Newton",
"objectclass" => array("simpleSecurityObject", "dcObject", "organization"),
"uid" => "Newton",
"mail" => "newton@ldap.forumsys.com",
"cn" => "Isaac Newton")
);
function echo1($n){
echo "<pre>";
echo $n;
echo "</pre>";
}
$i=0;
$hi1 = "";
$attributes_list = array("dn", "objectclass", "cn", "userpassword", "description", "sn", "uid", "mail");
echo "<pre></pre>";
$comma_separated = implode(",", $attributes_list);
echo $comma_separated;
foreach ( $movies as $movie => $val ) {
//echo "<pre></pre> \n Entry #$i";
//This prints the name of all the arrays.
//echo1($movie);
echo "<pre></pre>";
echo $movie.",";
$i = $i + 1;
//Checks if the value of the key value pair is an array.
if(is_array($val)){
//Since it's an array, we access its key value pairs again
foreach ( $val as $key => $value ) {
//Check to see if value of key value pair is array
if(is_array($value)){
//Prints the name of all the arrays
echo $key." ";
//Prints all key value pairs of the array
$value_array = implode(",", $value);
print_r($value_array);
//If $value isn't an array, just prints the key value pairs
} else{
/*This is the original code for easier readability
$hi = "$key : $value";
echo1($hi);*/
$hi1 = $hi1.$value.",";
echo $hi1;
}
}
//If $val isn't an array, prints the key value pairs
} else{
foreach ( $val as $key => $value ) {
$hi = "The key is: $key The value is:$value";
echo1($hi);
}
}
echo '</dl>';
}
?>
这是输出:
dn,objectclass,cn,userpassword,description,sn,uid,mail
dc=example,dc=com,example.com,objectclass simpleSecurityObject,dcObject,organizationexample.com,example,
uid=newton,dc=example,dc=com,example.com,example,Newton,objectclass simpleSecurityObject,dcObject,organizationexample.com,example,Newton,Newton,example.com,example,Newton,Newton,newton@ldap.forumsys.com,example.com,example,Newton,Newton,newton@ldap.forumsys.com,Isaac Newton,
编辑:
使用 Nigel Ren 的代码,我得到了这个输出。
distinguishedname,o,objectclass,dc,sn,uid,mail,cn
o,{}
objectclass,,{},,,,,,simpleSecurityObject,dcObject,organization
dc,{}
sn,{}
objectclass,,{},,,,,,simpleSecurityObject,dcObject,organization
uid,{}
mail,{}
cn,{}
这是我试过的确切代码:
<?php
// Start with the column list and split into an array
$headers = explode(',', 'distinguishedname,o,objectclass,dc,sn,uid,mail,cn');
// Create template record with the fields you want to end up with
$header = array_fill_keys($headers, null);
$output = [];
$details = array(
"dc=example,dc=com" => array(
"o" => "example.com",
"objectclass" => array("simpleSecurityObject", "dcObject", "organization"),
"dc" => "example"),
"uid=newton,dc=example,dc=com" => array(
"sn" => "Newton",
"objectclass" => array("simpleSecurityObject", "dcObject", "organization"),
"uid" => "Newton",
"mail" => "newton@ldap.forumsys.com",
"cn" => "Isaac Newton")
);
foreach ( $details as $detail ) {
foreach ( $detail as $name => $entry ) {
// Set the values in the template header from the current entry
$newEntry = array_merge( $header, $entry );
// Add the name in
$newEntry ['distinguishedname'] = $name;
// Process the object class from an array to a string
$newEntry ['objectclass'] = "{".implode(",", $newEntry ['objectclass'])."}";
$output [] = $newEntry;
}
}
// Write file out
$fh = fopen("ad.csv", "w");
fputcsv($fh, $headers);
foreach ( $output as $row ) {
fputcsv($fh, $row);
}
fclose($fh);
?>
编辑 2020 年 7 月 1 日:
这是我得到的输出
firstname,lastname,email,phone,uid
,,,,,"{top,dcObject,organization}",ec_testing,test123,"{organizationalPerson,person,top,user}"
,,,,,"{simpleSecurityObject,organizationalRole}",admin,"LDAP administrator",{SSHA}0NhB8bVqiqCfUjU7AGE2mtrfj3Q58mj5
,,,,,organizationalUnit,people
,,,,,organizationalUnit,"groups "
,,,,tnguyen,"{top,account,posixAccount,shadowAccount}",tnguyen,16859,100,/home/tnguyen,/bin/bash,tnguyen,{crypt}x,0,0,0
,,,,,"{top,organizationalRole,simpleSecurityObject}","{replica,test}",aDifferentSecret,"Bind object used for replication using slurpd"
,,,,,"{php testing,phptest}",person,TestEdit
,,,,,person,"This is just a test to add an entry in Java",javatest,replacetest
,,,,,gotest,person,Google,"this is to test if replacing works in GoLang"
这是我使用的代码:
foreach ( $details as $name => $entry ) {
// Set the values in the template header from the current entry
$newEntry = array_merge( $header, $entry );
// Add the name in
foreach ( $newEntry as &$entry ) {
if ( is_array($entry)) {
$entry = "{".implode(",", $entry)."}";
}
}
unset($entry);
//$newEntry ['distinguishedname'] = $name;
$output [] = $newEntry;
}
我希望输出像
firstname,lastname,email,phone,uid
,,,,
,,,,
,,,,
,,,,
,,,,tnguyen
,,,,
,,,,
,,,,
,,,,
这是一个糟糕的例子,因为所有条目都缺少大部分(如果不是全部的话)属性,但你明白了。
我试过的是这样的:
foreach ( $details as $name => $entry ) {
// Set the values in the template header from the current entry
if(in_array($entry, $header) || in_array($name, $header)){
$newEntry = array_merge( $header, $entry );
}
// Add the name in
foreach ( $newEntry as &$entry ) {
if ( is_array($entry) && in_array($newEntry, $header)) {
$entry = "{".implode(",", $entry)."}";
}
}
unset($entry);
//$newEntry ['distinguishedname'] = $name;
$output [] = $newEntry;
}
但它只输出我的 headers 而不是空条目。
firstname,lastname,email,phone,uid
以下代码创建一个模板数组,以便每条记录包含所有值,然后使用 array_merge()
将每条记录中的值复制到模板中。任何不在记录中的值都将保持为空,以确保保持对齐(代码注释中有更多描述)...
// Start with the column list and split into an array
$headers = explode(',', 'distinguishedname,o,objectclass,dc,sn,uid,mail,cn');
// Create template record with the fields you want to end up with
$header = array_fill_keys($headers, null);
$output = [];
foreach ( $details as $detail ) {
foreach ( $detail as $name => $entry ) {
// Set the values in the template header from the current entry
$newEntry = array_merge( $header, $entry );
// Add the name in
$newEntry ['distinguishedname'] = $name;
// Process the object class from an array to a string
$newEntry ['objectclass'] = "{".implode(",", $newEntry ['objectclass'])."}";
$output [] = $newEntry;
}
}
// Write file out
$fh = fopen("ad.csv", "w");
fputcsv($fh, $headers);
foreach ( $output as $row ) {
fputcsv($fh, $row);
}
fclose($fh);
样本数据给出...
distinguishedname,o,objectclass,dc,sn,uid,mail,cn
"dc=example,dc=com",example.com,"{simpleSecurityObject,dcObject,organization}",example,,,,
"uid=newton,dc=example,dc=com",,"{simpleSecurityObject,dcObject,organization}",,Newton,Newton,newton@ldap.forumsys.com,"Isaac Newton"
请注意,使用 fpustcsv()
的优点是,如果字段包含逗号(分隔符),那么它会将它们放在引号中以确保它们只是一个字段。
编辑:
$headers = explode(',', 'distinguishedname,o,objectclass,dc,sn,uid,mail,cn');
$output = [];
foreach ( $details as $name => $entry ) {
echo $name.PHP_EOL;
$newEntry = [];
foreach ( $headers as $header ) {
$value = $entry[$header] ?? null;
if ( is_array($value) ) {
$value = "{".implode(",", $value)."}";
}
$newEntry [$header] = $value;
}
$newEntry ['distinguishedname'] = $name;
$output [] = $newEntry;
}
我在输出空格和确保我的所有 CSV 数据都输出到正确位置时遇到了一些问题,我想知道我该如何做到这一点。
我正在尝试将 LDAP 服务器搜索的输出格式化为 CSV 格式,但问题是某些条目的属性顺序不正确,或者某些条目的属性完全缺失。
这是一些数据的例子
Array
(
[0] => Array
(
[dc=example,dc=com] => Array
(
[o] => example.com
[objectclass] => Array
(
[0] => simpleSecurityObject
[1] => dcObject
[2] => organization
)
[dc] => example
)
)
[1] => Array
(
[uid=newton,dc=example,dc=com] => Array
(
[sn] => Newton
[objectclass] => Array
(
[0] => simpleSecurityObject
[1] => dcObject
[2] => organization
)
[uid] => Newton
[mail] => newton@ldap.forumsys.com
[cn] => Isaac Newton
)
)
)
请注意,在第一个 ([0]) 数组中,我有一个名为“o”和“dc”的条目,而在第二个数组中,我没有。
所以基本上,我想输出这个:
distinguishedname,o,objectclass,dc,sn,uid,mail,cn
dc=example,dc=com,example.com,{simpleSecurityObject,dcObject,organization},example, , , ,
uid=newton,dc=example,dc=com, ,{simpleSecurityObject,dcObject,organization}, , ,Newton,newton@ldap.forumsys.com,Isaac Newton
我不太确定如何做两件事:
- 确保将所有缺失的属性替换为“”,使其显示为空
- 确保将正确的属性放在正确的位置。例如,“o”可能是一个条目中的第 3 个属性,但它可能是另一个条目中的第 6 个属性。如何确保我的 CSV 数据按以下顺序排列:
distinguishedname,o,objectclass,dc,sn,uid,mail,cn
这是一些以 CSV 格式输出所有数据的代码,但我不确定如何制作空字段并使它们对齐。输出只是所有数据的打印。
<?php
$movies = array(
"dc=example,dc=com" => array(
"o" => "example.com",
"objectclass" => array("simpleSecurityObject", "dcObject", "organization"),
"dc" => "example"),
"uid=newton,dc=example,dc=com" => array(
"sn" => "Newton",
"objectclass" => array("simpleSecurityObject", "dcObject", "organization"),
"uid" => "Newton",
"mail" => "newton@ldap.forumsys.com",
"cn" => "Isaac Newton")
);
function echo1($n){
echo "<pre>";
echo $n;
echo "</pre>";
}
$i=0;
$hi1 = "";
$attributes_list = array("dn", "objectclass", "cn", "userpassword", "description", "sn", "uid", "mail");
echo "<pre></pre>";
$comma_separated = implode(",", $attributes_list);
echo $comma_separated;
foreach ( $movies as $movie => $val ) {
//echo "<pre></pre> \n Entry #$i";
//This prints the name of all the arrays.
//echo1($movie);
echo "<pre></pre>";
echo $movie.",";
$i = $i + 1;
//Checks if the value of the key value pair is an array.
if(is_array($val)){
//Since it's an array, we access its key value pairs again
foreach ( $val as $key => $value ) {
//Check to see if value of key value pair is array
if(is_array($value)){
//Prints the name of all the arrays
echo $key." ";
//Prints all key value pairs of the array
$value_array = implode(",", $value);
print_r($value_array);
//If $value isn't an array, just prints the key value pairs
} else{
/*This is the original code for easier readability
$hi = "$key : $value";
echo1($hi);*/
$hi1 = $hi1.$value.",";
echo $hi1;
}
}
//If $val isn't an array, prints the key value pairs
} else{
foreach ( $val as $key => $value ) {
$hi = "The key is: $key The value is:$value";
echo1($hi);
}
}
echo '</dl>';
}
?>
这是输出:
dn,objectclass,cn,userpassword,description,sn,uid,mail
dc=example,dc=com,example.com,objectclass simpleSecurityObject,dcObject,organizationexample.com,example,
uid=newton,dc=example,dc=com,example.com,example,Newton,objectclass simpleSecurityObject,dcObject,organizationexample.com,example,Newton,Newton,example.com,example,Newton,Newton,newton@ldap.forumsys.com,example.com,example,Newton,Newton,newton@ldap.forumsys.com,Isaac Newton,
编辑:
使用 Nigel Ren 的代码,我得到了这个输出。
distinguishedname,o,objectclass,dc,sn,uid,mail,cn
o,{}
objectclass,,{},,,,,,simpleSecurityObject,dcObject,organization
dc,{}
sn,{}
objectclass,,{},,,,,,simpleSecurityObject,dcObject,organization
uid,{}
mail,{}
cn,{}
这是我试过的确切代码:
<?php
// Start with the column list and split into an array
$headers = explode(',', 'distinguishedname,o,objectclass,dc,sn,uid,mail,cn');
// Create template record with the fields you want to end up with
$header = array_fill_keys($headers, null);
$output = [];
$details = array(
"dc=example,dc=com" => array(
"o" => "example.com",
"objectclass" => array("simpleSecurityObject", "dcObject", "organization"),
"dc" => "example"),
"uid=newton,dc=example,dc=com" => array(
"sn" => "Newton",
"objectclass" => array("simpleSecurityObject", "dcObject", "organization"),
"uid" => "Newton",
"mail" => "newton@ldap.forumsys.com",
"cn" => "Isaac Newton")
);
foreach ( $details as $detail ) {
foreach ( $detail as $name => $entry ) {
// Set the values in the template header from the current entry
$newEntry = array_merge( $header, $entry );
// Add the name in
$newEntry ['distinguishedname'] = $name;
// Process the object class from an array to a string
$newEntry ['objectclass'] = "{".implode(",", $newEntry ['objectclass'])."}";
$output [] = $newEntry;
}
}
// Write file out
$fh = fopen("ad.csv", "w");
fputcsv($fh, $headers);
foreach ( $output as $row ) {
fputcsv($fh, $row);
}
fclose($fh);
?>
编辑 2020 年 7 月 1 日:
这是我得到的输出
firstname,lastname,email,phone,uid
,,,,,"{top,dcObject,organization}",ec_testing,test123,"{organizationalPerson,person,top,user}"
,,,,,"{simpleSecurityObject,organizationalRole}",admin,"LDAP administrator",{SSHA}0NhB8bVqiqCfUjU7AGE2mtrfj3Q58mj5
,,,,,organizationalUnit,people
,,,,,organizationalUnit,"groups "
,,,,tnguyen,"{top,account,posixAccount,shadowAccount}",tnguyen,16859,100,/home/tnguyen,/bin/bash,tnguyen,{crypt}x,0,0,0
,,,,,"{top,organizationalRole,simpleSecurityObject}","{replica,test}",aDifferentSecret,"Bind object used for replication using slurpd"
,,,,,"{php testing,phptest}",person,TestEdit
,,,,,person,"This is just a test to add an entry in Java",javatest,replacetest
,,,,,gotest,person,Google,"this is to test if replacing works in GoLang"
这是我使用的代码:
foreach ( $details as $name => $entry ) {
// Set the values in the template header from the current entry
$newEntry = array_merge( $header, $entry );
// Add the name in
foreach ( $newEntry as &$entry ) {
if ( is_array($entry)) {
$entry = "{".implode(",", $entry)."}";
}
}
unset($entry);
//$newEntry ['distinguishedname'] = $name;
$output [] = $newEntry;
}
我希望输出像
firstname,lastname,email,phone,uid
,,,,
,,,,
,,,,
,,,,
,,,,tnguyen
,,,,
,,,,
,,,,
,,,,
这是一个糟糕的例子,因为所有条目都缺少大部分(如果不是全部的话)属性,但你明白了。
我试过的是这样的:
foreach ( $details as $name => $entry ) {
// Set the values in the template header from the current entry
if(in_array($entry, $header) || in_array($name, $header)){
$newEntry = array_merge( $header, $entry );
}
// Add the name in
foreach ( $newEntry as &$entry ) {
if ( is_array($entry) && in_array($newEntry, $header)) {
$entry = "{".implode(",", $entry)."}";
}
}
unset($entry);
//$newEntry ['distinguishedname'] = $name;
$output [] = $newEntry;
}
但它只输出我的 headers 而不是空条目。
firstname,lastname,email,phone,uid
以下代码创建一个模板数组,以便每条记录包含所有值,然后使用 array_merge()
将每条记录中的值复制到模板中。任何不在记录中的值都将保持为空,以确保保持对齐(代码注释中有更多描述)...
// Start with the column list and split into an array
$headers = explode(',', 'distinguishedname,o,objectclass,dc,sn,uid,mail,cn');
// Create template record with the fields you want to end up with
$header = array_fill_keys($headers, null);
$output = [];
foreach ( $details as $detail ) {
foreach ( $detail as $name => $entry ) {
// Set the values in the template header from the current entry
$newEntry = array_merge( $header, $entry );
// Add the name in
$newEntry ['distinguishedname'] = $name;
// Process the object class from an array to a string
$newEntry ['objectclass'] = "{".implode(",", $newEntry ['objectclass'])."}";
$output [] = $newEntry;
}
}
// Write file out
$fh = fopen("ad.csv", "w");
fputcsv($fh, $headers);
foreach ( $output as $row ) {
fputcsv($fh, $row);
}
fclose($fh);
样本数据给出...
distinguishedname,o,objectclass,dc,sn,uid,mail,cn
"dc=example,dc=com",example.com,"{simpleSecurityObject,dcObject,organization}",example,,,,
"uid=newton,dc=example,dc=com",,"{simpleSecurityObject,dcObject,organization}",,Newton,Newton,newton@ldap.forumsys.com,"Isaac Newton"
请注意,使用 fpustcsv()
的优点是,如果字段包含逗号(分隔符),那么它会将它们放在引号中以确保它们只是一个字段。
编辑:
$headers = explode(',', 'distinguishedname,o,objectclass,dc,sn,uid,mail,cn');
$output = [];
foreach ( $details as $name => $entry ) {
echo $name.PHP_EOL;
$newEntry = [];
foreach ( $headers as $header ) {
$value = $entry[$header] ?? null;
if ( is_array($value) ) {
$value = "{".implode(",", $value)."}";
}
$newEntry [$header] = $value;
}
$newEntry ['distinguishedname'] = $name;
$output [] = $newEntry;
}