【问题标题】:Reading text file读取文本文件
【发布时间】:2013-01-26 09:21:02
【问题描述】:

我们有一家供应商,每个星期一都会发送一份新设备/零件列表,然后将这些设备/零件手动输入数据库。

我想使用 PHP 来读取这个文件并更新相应的数据库记录。 数据库我可以做,但是如何从文件中读取数据呢?

System:         Avro
Supplier:       ABC Inc

Quantity:       1
Device:             ICD
ID:           PA-658_ao8uY
For Clarity:  PA-658_AO8UY

Quantity:       10
Device:             PSTHG
ID:              tg675_0O09i8
For Clarity:  TG675_0O09I8

上面是我们得到的一个例子。系统就是我们,供应商就是他们。 在我们收到的文件中,数量、设备 ID 和清晰度行可能有数百行。

如何将系统/供应商名称转换为变量,然后遍历每个数量、设备、ID 和清晰度条目???

【问题讨论】:

  • 那么您的问题是读取文件,而不是解析其内容?
  • 您可以使用 RegEx 解析文件,但我认为它不可靠,因为如果标记发生更改,您最终可能会在数据库中得到格式错误的数据。我建议与他们联系并要求他们发送第二个文件,其中包含更适合解析的数据格式,例如 XML 或 JSON。
  • 嗨。对不起,如果我措辞不好。问题是从文件中获取数据,以便我可以将其写入数据库。
  • 我想问题在于读取和解析文件。您能否要求您的供应商更改此格式?例如 CSV、XML、JSON?使用一些标准格式从中提取数据会更容易更好。
  • 这种格式稳定吗?容易改变?因为你不能有一个通用的方法来解决这个问题,你需要一个完全定制的解决方案。

标签: php flat-file


【解决方案1】:

如果您可以将此文件的格式重新定义为类似这样..

   [Core]
        System=Avro
        Supplier=ABC Inc

   [line1]   
        Quantity= 1
        Device=ICD
        ID=PA-658_ao8uY
        For Clarity=PA-658_AO8UY

   [line2]
        Quantity=10
        Device=PSTHG
        ID=tg675_0O09i8
        For Clarity:  TG675_0O09I8

你可以使用parse_ini_file(file,true,INI_SCANNER_NORMAL)可以给你一个包含所有数据的多维数组。

这是您可以使用的另一种高度主观的解决方案。我只是假设格式是稳定的,并且会保持很长时间。

<?php

$newStock = new NewStockUpdate($itemListFile);

//do anything with $newStock Object




class NewStockUpdate
{

    private $System;
    private $Supplier;
    private $allUpdates;


    function __construct($listFile)
    {

    $fileHandle = fopen( $listFile, "r" ) or die("Couldn't open Update file $listFile");


    $lineSystem = explode(":",getLineData($fileHandle));
    $lineSupplier = explode(":",getLineData($fileHandle));

    $i=0;
        while(true)
        {

        $allUpdates[$i] = new ItemData($fileHandle);
        $i++;



        }

    }

    function getSystem()
    {
    return $this->System;
    }

    function getSupplier()
    {
    return $this->Supplier;
    }

    function getUpdateList()
    {
     return $this->allUpdates;
    }

}



class ItemData
{

public $Quantity;
public $Device;
public $ID;
public $ForClarity;

public $lastObject;

function __construct($filePointer)
{

    try
    {

    $lineQuantity = explode(":",getLineData($filePointer));
    $lineDevice = explode(":",getLineData($filePointer));
    $lineID = explode(":",getLineData($filePointer));
    $lineForClarity = explode(":",getLineData($filePointer));

    $this->Quantity = $lineQuantity[1];
    $this->Device = $lineDevice[1];
    $this->ID = $lineID[1];
    $this->ForClarity = $lineForClarity[1];

    }
    catch(Exception $e)
    {
     //log something
    }

    if(feof($filePointer))
    {

    $this->lastObject = true;

    }
    else
    {
    $this->lastObject=false;
    }

    function isLastRecord()
    {
        return $this->lastObject;
    }


}



}



function getLineData($filePointer)
{

while(!feof($filePointer))
{

$data = fgets($filePointer);
if(empty($data)|| $data=='\n')
{
$data = fgets($filePointer);
}
else
{
return $data;
}
}



}

?>

我认为其余的你可以用类对象来管理。将这些条目添加到 db 和所有。您可以为各种供应商创建多个 NewStock 对象。希望这会有所帮助

【讨论】:

  • 感谢您的回答。供应商将相同格式的文件发送给许多经销商。我不认为他们会为我改变它。格式始终位于 4 数量、设备、ID、清晰度的块中。希望这会有所帮助!
  • 也许你可以试试这个。
【解决方案2】:

对于这个不需要正则表达式的简单任务,下面的代码就可以了。

$content = file_get_contents("file.txt");
$content = str_replace(Array("\r\n", "\r"), "\n", $content); // we only want unix linebreaks

$data = explode("\n\n", $content);
foreach($data as &$section) {
  $lines = explode("\n", $section);
  $section = Array();
  foreach($lines as $line) {
    $colon = strpos($line, ":");
    $section[substr($line, 0, $colon)] = trim(substr($line, $colon + 1));
  }
}

print_r($data);

样本输出数据:

Array
(
    [0] => Array
        (
            [System] => Avro
            [Supplier] => ABC Inc
        )

    [1] => Array
        (
            [Quantity] => 1
            [Device] => ICD
            [ID] => PA-658_ao8uY
            [For Clarity] => PA-658_AO8UY
        )

    [2] => Array
        (
            [Quantity] => 10
            [Device] => PSTHG
            [ID] => tg675_0O09i8
            [For Clarity] => TG675_0O09I8
        )

)

【讨论】:

  • 谢谢。这可行,但第一个数组 [0] 包含:[0] =&gt; Array ( [System] =&gt; Avro [Supplier] =&gt; ABC Inc [Quantity] =&gt; 1 [Device] =&gt; ICD [ID] =&gt; PA-658_ao8uY [For Clarity] =&gt; PA-658_AO8UY )
  • 哎呀。我的文件在 2 个条目之间没有换行。
  • 使用 fopen()、fread() 和 fclose() 代替 file_get_contents()
【解决方案3】:
    $handle = fopen("your file ");
    //counter
    $i=0;
    $rowContentPrec=array();
    while (!feof($handle)) {
     $rowContent=explode(':',fread($handle, 8192));
     //get the system and provider
      if($i==0){      
          $sytem=$rowContent[1];
      }elseif($i==1){
          $provider=$rowContent[1];  
      }elseif(isset($rowContent)){ 
          //product
          $rowContent=explode(':',fread($handle, 8192));
          if($rowContentPrec[0]=='For Clarity'){
               //save your product to database here and initialize the    array with informations about one product
                $contentArr=array();
          }else{
            $contentArr[$rowContent[0]]=$rowContent[1];  
          } 
           $rowContentPrec=$rowContent;
          $i++; 
      }

    }
    fclose($handle);

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-03-10
    • 2016-08-08
    • 2015-05-16
    • 2021-12-22
    相关资源
    最近更新 更多