tags:

views:

154

answers:

2

This used to work fine until last night, it appears the source file changed, so I changed my explode to try and fix it but I still get the error.

The source code definition tells me the fields are:

#export_date^Aapplication_id^Alanguage_code^Atitle^Adescription^Arelease_notes^Acompany_url^Asupport_url^Ascreenshot_url_1^Ascreenshot_url_2^Ascreenshot_url_3^Ascreenshot_url_4^Ascreenshot_width_height_1^Ascreenshot_width_height_2^Ascreenshot_width_height_3^Ascreenshot_width_height_4^Aipad_screenshot_url_1^Aipad_screenshot_url_2^Aipad_screenshot_url_3^Aipad_screenshot_url_4^Aipad_screenshot_width_height_1^Aipad_screenshot_width_height_2^Aipad_screenshot_width_height_3^Aipad_screenshot_width_height_4^B

#dbTypes:BIGINT^AINTEGER^AVARCHAR(20)^AVARCHAR(1000)^ALONGTEXT^ALONGTEXT^AVARCHAR(1000)^AVARCHAR(1000)^AVARCHAR(1000)^AVARCHAR(1000)^AVARCHAR(1000)^AVARCHAR(1000)^AVARCHAR(20)^AVARCHAR(20)^AVARCHAR(20)^AVARCHAR(20)^AVARCHAR(1000)^AVARCHAR(1000)^AVARCHAR(1000)^AVARCHAR(1000)^AVARCHAR(20)^AVARCHAR(20)^AVARCHAR(20)^AVARCHAR(20)^B

My code is

$eoldelimiter = chr(2) . "\n";
$delimiter = chr(1);
    while (!feof($fp3)) {
        $line = stream_get_line($fp3,8000,$eoldelimiter); 
        if ($line[0] === '#') continue;  //Skip lines that start with # 
        list($export_date, $application_id, $language_code, $title, $description, $release_notes, $company_url, $suppport_url, $screenshot_url_1, $screenshot_url_2, $screenshot_url_3, $screenshot_url_4, $screenshot_width_height_1, $screenshot_width_height_2, $screenshot_width_height_3, $screenshot_width_height_4,$ipadscreenshot_url_1, $ipadscreenshot_url_2, $ipadscreenshot_url_3, $ipadscreenshot_url_4, $ipadscreenshot_width_height_1, $ipadscreenshot_width_height_2, $ipadscreenshot_width_height_3, $ipadscreenshot_width_height_4 ) = explode($delimiter, $line);
    } // end while statement

and the error I get on screen is

PHP Notice: Undefined offset: 23 in /var/www/vhosts/httpdocs/fred/daily_iapps_to_mysql.php on line 73

Notice: Undefined offset: 23 in /var/www/vhosts/httpdocs/fred/daily_iapps_to_mysql.php on line 73 PHP Notice: Undefined offset: 22 in /var/www/vhosts/httpdocs/fred/daily_iapps_to_mysql.php on line 73

Notice: Undefined offset: 22 in /var/www/vhosts/httpdocs/fred/daily_iapps_to_mysql.php on line 73 PHP Notice: Undefined offset: 21 in /var/www/vhosts/httpdocs/fred/daily_iapps_to_mysql.php on line 73

Notice: Undefined offset: 21 in /var/www/vhosts/httpdocs/fred/daily_iapps_to_mysql.php on line 73 PHP Notice: Undefined offset: 20 in /var/www/vhosts/httpdocs/fred/daily_iapps_to_mysql.php on line 73

Notice: Undefined offset: 20 in /var/www/vhostshttpdocs/fred/daily_iapps_to_mysql.php on line 73 PHP Notice: Undefined offset: 19 in /var/www/vhosts/httpdocs/fred/daily_iapps_to_mysql.php on line 73

+1  A: 

It seems explode($delimiter, $line) doesn't give the right number of elements.

You should print_r the result of explode to see if it's the case.

M42
+1  A: 

In addition to M42's answer: I'd suggest using something like

$eoldelimiter = chr(2) . "\n";
$delimiter = chr(1);
$cols = array( // you can even derive this from the comment line ...if you want to.
  'export_date', 'application_id', 'language_code', 'title',
  'description', 'release_notes', 'company_url', 'suppport_url',
  'screenshot_url_1', 'screenshot_url_2', 'screenshot_url_3', 'screenshot_url_4',
  'screenshot_width_height_1', 'screenshot_width_height_2', 'screenshot_width_height_3', 'screenshot_width_height_4',
  'ipadscreenshot_url_1', 'ipadscreenshot_url_2', 'ipadscreenshot_url_3', 'ipadscreenshot_url_4',
  'ipadscreenshot_width_height_1', 'ipadscreenshot_width_height_2', 'ipadscreenshot_width_height_3', 'ipadscreenshot_width_height_4'
);

$fp3 = fopen('test.txt', 'rb');
$data = array();
while( !feof($fp3) ) {
  $line = stream_get_line($fp3, 8000, $eoldelimiter); 
  if ( '#'===$line[0] ) {
    continue;
  }

  $row = explode($delimiter, $line);
  if ( count($row) != count($cols) ) {
    echo 'wrong number of fields: (', count($row), ') ', $line, "\n";
  }
  else {
    $row = array_combine($cols, $row);
  }
  $data[] = $row;
}

instead of using 24 independent variables and list()


update: You might be interested in MySQL's LOAD DATA INFILE and/or prepared, parametrized statements, e.g. via PHP Data Objects (pdo).
But anyway, here's an example (example, not production code) for building a query string...

$eoldelimiter = chr(2) . "\n";
$delimiter = chr(1);
$cols = array( // you can even derive this from the comment line ...if you want to.
  'export_date', 'application_id', 'language_code', 'title',
  'description', 'release_notes', 'company_url', 'suppport_url',
  'screenshot_url_1', 'screenshot_url_2', 'screenshot_url_3', 'screenshot_url_4',
  'screenshot_width_height_1', 'screenshot_width_height_2', 'screenshot_width_height_3', 'screenshot_width_height_4',
  'ipadscreenshot_url_1', 'ipadscreenshot_url_2', 'ipadscreenshot_url_3', 'ipadscreenshot_url_4',
  'ipadscreenshot_width_height_1', 'ipadscreenshot_width_height_2', 'ipadscreenshot_width_height_3', 'ipadscreenshot_width_height_4'
);
$mysql = mysql_connect(...) or trigger_error(mysql_error());
mysql_select_db('test', $mysql) or trigger_error(mysql_error($mysql));

$sql_pre= 'INSERT INTO foo (' . join($cols, ',') . ') VALUES (';
$fp3 = fopen('test.txt', 'rb') or trigger_error('fopen failed');
while( !feof($fp3) ) {
  $line = stream_get_line($fp3, 8000, $eoldelimiter); 
  if ( '#'===$line[0] ) {
    continue;
  }

  $row = explode($delimiter, $line);
  if ( count($row) != count($cols) ) {
    echo 'wrong number of fields: (', count($row), ') ', $line, "\n";
  }
  else {
    // the & in &$col will only work with php5+
     foreach( $row as &$col ) {   
       $col = "'".mysql_real_escape_string($col, $mysql)."'";
     }
    $sql = $sql_pre . join(',', $row) . ')';
    echo $sql, "\n";
  }
}
VolkerK
unfortunately that code gave me a memory error - PHP Fatal error: Allowed memory size of 33554432 bytes exhausted (tried to allocate 641 bytes) in /var/www/vhosts/httpdocs/fred/test.php on line 80 which is this line $line = stream_get_line($fp3, 8000, $eoldelimiter);
kitenski
Storing all rows in $data was only an example ...obviously one that isn't feasible in your case ;-) Just replace `$data[]=$row;` by whatever you want to do with a single row.
VolkerK
sorry but I am fairly new to this and don't quite understand the answer. After the explode I do a MySQL insert so I need each of the fields within a variable so I can perform an insert statement. I am really sorry but I can't see how I do that from your example code.
kitenski
Do you use queries like "INSERT ... VALUES ('a', 'b', 'c')" (i.e. the parameters/data mixed into the actual sql statement, e.g. via mysql_query()) or do you use prepared, parametrized statements (e.g. via $pdo->prepare())?
VolkerK
I use the first type in your example, INSERT ... VALUES ('a', 'b', 'c')"
kitenski