4

我正在努力尝试从每月收到的 CSV 文件自动更新我们的 SugarCRM 系统中的某些记录。

背景/介绍

我正在使用 Sugar 提供的以下代码通过 REST 更新/创建记录。

<?php

include_once('parsecsv.lib.php');  // Include the parsecsv-for-php library

$csv = new parseCSV('myCSV.csv'); // Parse through the CSV and store results in $csv

$url = "http://{site_url}/service/v4/rest.php";
$username = "admin";
$password = "password";

//function to make cURL request
function call($method, $parameters, $url)
{
    ob_start();
    $curl_request = curl_init();

    curl_setopt($curl_request, CURLOPT_URL, $url);
    curl_setopt($curl_request, CURLOPT_POST, 1);
    curl_setopt($curl_request, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0);
    curl_setopt($curl_request, CURLOPT_HEADER, 1);
    curl_setopt($curl_request, CURLOPT_SSL_VERIFYPEER, 0);
    curl_setopt($curl_request, CURLOPT_RETURNTRANSFER, 1);
    curl_setopt($curl_request, CURLOPT_FOLLOWLOCATION, 0);

    $jsonEncodedData = json_encode($parameters);

    $post = array(
         "method" => $method,
         "input_type" => "JSON",
         "response_type" => "JSON",
         "rest_data" => $jsonEncodedData
    );

    curl_setopt($curl_request, CURLOPT_POSTFIELDS, $post);
    $result = curl_exec($curl_request);
    curl_close($curl_request);

    $result = explode("\r\n\r\n", $result, 2);
    $response = json_decode($result[1]);
    ob_end_flush();

    return $response;
}

//login -----------------------------------------------

$login_parameters = array(
     "user_auth"=>array(
          "user_name"=>$username,
          "password"=>md5($password),
          "version"=>"1"
     ),
     "application_name"=>"RestTest",
     "name_value_list"=>array(),
);

$login_result = call("login", $login_parameters, $url);

/*
echo "<pre>";
print_r($login_result);
echo "</pre>";
*/

//get session id
$session_id = $login_result->id;

//create contacts ---------------------------------------

$set_entries_parameters = array(
     //session id
     "session" => $session_id,

     //The name of the module from which to retrieve records.
     "module_name" => "Accounts",

     //Record attributes
     "name_value_list" => array(
         array(
            //to update a record, you will nee to pass in a record id as commented below
            array("name" => "id", "value" => "111111111"),
            array("name" => "jan_field_1", "value" => "Sample Value 1"),
            array("name" => "jan_field_2", "value" => "Sample Value 2"),
            // more fields could be added here
         ),
         array(
            //to update a record, you will nee to pass in a record id as commented below
            array("name" => "id", "value" => "222222222"),
            array("name" => "jan_field_1", "value" => "Sample Value 1"),
            array("name" => "jan_field_2", "value" => "Sample Value 2"),
            // more fields could be added here
         ),
     ),
);

$set_entries_result = call("set_entries", $set_entries_parameters, $url);

echo "<pre>";
print_r($set_entries_result);
echo "</pre>";

?>

如果我硬编码 $set_entries_parameters 数组中的值,一切正常,例如:

//Record attributes
     "name_value_list" => array(
         array(
            //to update a record, you will need to pass in a record id as commented below
            array("name" => "id", "value" => "111111111"),
            array("name" => "jan_field_1", "value" => "Sample Value 1"),
            array("name" => "jan_field_2", "value" => "Sample Value 2"),
         ),
         array(
            //to update a record, you will need to pass in a record id as commented below
            array("name" => "id", "value" => "222222222"),
            array("name" => "jan_field_1", "value" => "Sample Value 1"),
            array("name" => "jan_field_2", "value" => "Sample Value 2"),
         ),
     ),
);

下面是print_r($set_entry_parameters['name_value_list'])最终传递给function call($method, $parameters, $url)as的打印输出$paramaters- 一切正常,并且每条记录的记录都已正确更新。

Array
(
[0] => Array
    (
        [0] => Array
            (
                [name] => id
                [value] => 111111111
            )

        [1] => Array
            (
                [name] => jan_field_1
                [value] => Sample Value 1
            )

        [2] => Array
            (
                [name] => jan_field_2
                [value] => Sample Value 2
            )

    )

[1] => Array
    (
        [0] => Array
            (
                [name] => id
                [value] => 222222222
            )

        [1] => Array
            (
                [name] => jan_field_1
                [value] => Sample Value 1
            )

        [2] => Array
            (
                [name] => jan_field_2
                [value] => Sample Value 2
            )

    )

)

我正在使用的 CSV 文件采用以下形式,其中 id 是 CRM 中记录的 id,每个附加列标题是要更新的字段以及应设置的值:

id,field_1,field_2,field_3,field_4,field_5,field_6
111111111,21,10,8,0,1,1
222222222,32,8,7,0,0,1
333333333,17,11,7,0,0,4

随着时间的推移,每个新月份都会将多个新列/标题添加到电子表格中。

我目前正在使用http://code.google.com/p/parsecsv-for-php/中的 parsecsv-for-php 库来解析 CSV 文件。$csv->data'该库在via中创建以下数组$csv = new parseCSV('myCSV.csv');

Array
(
[0] => Array
    (
        [id] => 111111111
        [field_1] => 21
        [field_2] => 10
        [field_3] => 8
        [field_4] => 0
        [field_5] => 1
        [field_6] => 1
    )

[1] => Array
    (
        [id] => 222222222
        [field_1] => 32
        [field_2] => 8
        [field_3] => 7
        [field_4] => 0
        [field_5] => 0
        [field_6] => 1
    )
)

问题/问题

最后是我正在努力解决的问题。

我需要找到一种方法来获取从 parsecsv-for-php 库创建的数组,并使 $set_entry_paramaters['name_value_list'] 最终传递给更新所有记录的函数。

在我上面的示例中,如果我用记录的 ID 对每个需要更新的子数组和每个需要更新的字段进行硬编码,那么一切正常。

但是该$csv->data数组每个月都会随着需要更新的新记录以及需要更新的新字段而变化。

我猜我需要以某种方式递归地将数组中的任何内容添加到$csv->data数组中,$set_entry_parameters['name_value_list']但键/索引$csv->data与需要发送的内容不匹配。

如您所见(希望),每个要更新的帐户都是它自己的数组:要更新的记录的 id 是一个子数组,每个要更新的字段也是一个子数组,但我解析的 CSV 数组并没有接近这个值。

所以在我看来,我有两个问题需要解决:

  1. 保存已解析 CSV 的数组需要与function call($method, $parameters, $url)接受为的数组的结构相匹配$paramaters
  2. function call($method, $parameters, $url)需要为每条需要更新的记录调用一次。

我已经研究过尝试在 PHP 中使用array_walkorcall_user_func_array方法,但我不确定这是否正确或我将如何去做。

我仍在学习 PHP,但我认为目前这真的超出了我的理解范围,但希望我可以学习如何做到这一点。我希望我已经提供了足够的信息,并希望有一个善良的灵魂可以帮助我。如果有帮助,我很乐意提供任何其他信息。

非常感谢您!

4

1 回答 1

1

首先,感谢您写出如此精美的第一个问题!

你是正确的,你的问题的答案是将你的$csv->data数组转换成你想要的格式,但它不一定是递归的,因为你知道它的深度和一切。您可能只想与它并排构建自己的数组,因为基本上您需要的是将您的$name => $value对转换$csv->data为它们自己的数组。

这是一个如何做到这一点的示例,请耐心等待,因为我的 php 语法技能已经很生疏了,所以如果需要,请使用一些伪代码:

$params = array();
foreach ($csv->data as $i => $pairs) {
    $csvline = array();
    foreach ($pairs as $name => $value) {
        $csvline[] = array('name'  => $name,
                           'value' => $value)
    }
    $params[$i] = $csvline; // in your case you may also do $params[] =...
}
$set_entry_parameters['name_value_list'] = $params;

瞧,$params是您预期的格式:)

编辑:

对于下面评论中的额外功能,一种简单的方法是将上面的代码放入一个接收$start参数的函数中,这样您就可以限制要解析的行数以及从哪里开始。例如:

function parse($start) {
    $params = array();
    foreach ($csv->data as $i => $pairs) {
        if($i < $start) continue; // skip it
        if($i == $start+10000) break; // we reached our limit, stop here
        $csvline = ...
    ...
    }
    return $params; // has at most 10000 entries
}

然后你会使用一个循环,比如

for($i = 0; $i < (total_lines); $i = $i + 10000) {
    $set_entry_parameters['name_value_list'] = parse($i);
    // call update
}

但是,如果实际上是您的初始 CSV 文件解析内存不足,您可能会发现手动(或以编程方式)将数据拆分为多个文件更简单。或者增加您允许 PHP 使用的内存限制!

于 2013-05-20T22:57:42.333 回答