【问题标题】:Creating a custom CSV importer for SilverStripe为 SilverStripe 创建自定义 CSV 导入器
【发布时间】:2015-07-23 20:39:09
【问题描述】:

我正在为 SilverStripe 网站构建自定义导入控件,因为不幸的是,要使用的 CSV 文件格式不正确,无法改进(我们必须使用我们提供的内容,基本上)。文件包含半色分隔数据,每一行是一个条目:

"[ID]";"[First Name]";"[Middle Initial]";"[Last Name]";"[Title]";"[University/College]";"[Specialty]";"[Graduation Date]"

这些值中的任何一个都可以为空(即,条目可能没有中间名首字母,或者可能没有列出的专业)。然后将这些字段标记为一对双引号内的单个空格:

"[ID]";"[First Name]";" ";"[Last Name]";"[Title]";"[University/College]";" ";"[Graduation Date]"

同样重要的是要注意 CSV 文件没有标题,而且它们不太可能有标题。我已经阅读了 SilverStripe 的 CSVBulkLoader 类,但似乎没有标题,很难使用它。另外,我提到的空字段存在问题。

是否可以设置一个文件,以分号分隔 CSV 文件中的数据?这样,我可以将每个值放在一行上,然后将它们映射到 SilverStripe 管理模型中的字段。

这是我目前正在研究的一个管理模型:

<?php
class PhysicianEducationAdmin extends ModelAdmin {

    private static $managed_models = array('PhysicianEducation');
    private static $url_segment = 'physicianeducation';
    private static $menu_title = 'Physician Education Info';

}

<?php

class PhysicianEducation extends DataObject {

    private static $db = array(
        'ProviderID' => 'varchar',
        'FirstName' => 'varchar(250)',
        'MiddleName' => 'varchar(250)',
        'LastName' => 'varchar(250)',
        'Title' => 'varchar(10)',
        'Institution' => 'varchar(550)',
        'Education' => 'varchar(250)',
        'Specialty' => 'varchar(250)',
        'EndDate' => 'Date',
    );

    public static $summary_fields = array(
        'ProviderID' => 'Provider ID',
        'FirstName' => 'First Name',
        'MiddleName' => 'Middle Initial',
        'LastName' => 'Last Name',
        'Title' => 'Title',
        'Institution' => 'Institution',
        'Education' => 'Education',
        'Specialty' => 'Speciality',
        'EndDate' => 'End Date',
    );

}

【问题讨论】:

    标签: php csv silverstripe


    【解决方案1】:

    您应该可以使用 fgetcsv() 函数http://php.net/manual/en/function.fgetcsv.php

    它允许您指定分隔符(为您提供';')和附件(为您提供'"'),这是默认设置。

    【讨论】:

      【解决方案2】:

      Silverstripe 包含可用于此目的的CSVParser class。您可以将分隔符作为构造函数的第二个参数传入。由于该文件没有标题行,您可以使用provideHeaderRow 函数为其提供一个标题行。 CSVParser 实现了 Iterator 接口,因此您可以在循环中循环对象:

      $physicians = CSVParser::create('myfile.csv', ';');
      $physicians->provideHeaderRow(array(...));
      
      foreach($physicians as $physician) {
        $pe = PhysicianEducation::create()->update($physician);
        $pe->write();
      }
      

      您需要向您的 DataObject 添加一些验证(可能在 onBeforeWrite 中进行一些检查,或者创建 Validator 的子类)以防止创建无效记录(例如空字段)。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-10-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多