PHP script is running out of memory - php

I wrote the following PHP script (symphony 1.4 Task), which loops over a CSV file an d imports the data via Doctrine into MySQL.
Unfortunately the script is aborted because it allocates to much memory. The used memory grows with each foreach cycle. I tried a lot of things, but i am not able to keep the used memory more stable.
Could anyone give me a hint?
<?php
class importERPTask extends sfBaseTask
{
protected function configure()
{
$this->addOptions(array(
new sfCommandOption('application', null, sfCommandOption::PARAMETER_REQUIRED, 'The application name', 'frontend'),
new sfCommandOption('env', null, sfCommandOption::PARAMETER_REQUIRED, 'The environment', 'dev'),
new sfCommandOption('connection', null, sfCommandOption::PARAMETER_REQUIRED, 'The connection name', 'doctrine'),
// add your own options here
));
$this->namespace = 'w2';
$this->name = 'importERP';
$this->briefDescription = 'Imports product data .';
}
public function execute($arguments = array(), $options = array())
{
// initialize the database connection
$databaseManager = new sfDatabaseManager($this->configuration);
$connection = $databaseManager->getDatabase($options['connection'])->getConnection();
$this->logSection('importERP', 'Start');
if(!(file_exists(sfConfig::get('sf_root_dir'). DIRECTORY_SEPARATOR .'import_data'.DIRECTORY_SEPARATOR.'VK.csv') && file_exists(sfConfig::get('sf_root_dir'). DIRECTORY_SEPARATOR .'import_data'.DIRECTORY_SEPARATOR.'Artikel.csv')))
{
$this->logSection('importERP', 'No import CSV');
$this->logSection('importERP', 'Done.');
return;
}
$this->importPrices();
//import products
$this->logSection('importERP', 'Import products');
Doctrine::getTable('CatalogueProduct')->setAllImportFalse();
$file_handle = fopen(sfConfig::get('sf_root_dir'). DIRECTORY_SEPARATOR .'import_data'.DIRECTORY_SEPARATOR.'Artikel.csv', 'r');
if($file_handle)
{
$i = 0;
while(!feof($file_handle))
{
//skip first line
if(++$i == 1)
{
continue;
}
$this->importProduct($file_handle);
}
fclose($file_handle);
}
$this->deleteProducts();
unlink(sfConfig::get('sf_root_dir'). DIRECTORY_SEPARATOR .'import_data'.DIRECTORY_SEPARATOR.'VK.csv');
unlink(sfConfig::get('sf_root_dir'). DIRECTORY_SEPARATOR .'import_data'.DIRECTORY_SEPARATOR.'Artikel.csv');
$this->logSection('importERP', 'Done.');
}
private function importPrices()
{
//import price helper table
$this->logSection('importERP', 'Import price helper table');
Doctrine::getTable('ImportHelperPrice')->clearAllData();
$file_handle = fopen(sfConfig::get('sf_root_dir'). DIRECTORY_SEPARATOR .'import_data'.DIRECTORY_SEPARATOR.'VK.csv', 'r');
if($file_handle)
{
$i = 0;
while(!feof($file_handle))
{
$line_of_text = fgetcsv($file_handle, 0, ';', '"');
//skip first line
if(++$i == 1)
{
continue;
}
$price = new ImportHelperPrice();
$price->setImportId($line_of_text[0]);
$price->setStartAmount($line_of_text[1]);
$price->setPrice(str_replace(',', '.', $line_of_text[2]));
$price->save();
}
}
}
private function importProduct($file_handle)
{
$line_of_text = fgetcsv($file_handle, 0, ';', '"');
$this->logSection('importERP', 'Import product '.$line_of_text[1]);
//no empty article number
if($line_of_text[0] == '')
{
$this->logSection('importERP', '... skipped');
return;
}
if($line_of_text[4] == '')
{
$this->logSection('importERP', '... has no category');
return;
}
$my_product = Doctrine::getTable('CatalogueProduct')->findOneByCode($line_of_text[0]);
$my_cat = Doctrine::getTable('CatalogueCategory')->findOneByImportCode($line_of_text[4]);
if(!$my_cat)
{
$this->logSection('importERP', '... has no category');
return;
}
if(!$my_product)
{
$this->logSection('importERP', '... is new');
$my_product = new CatalogueProduct();
$my_product->setCode($line_of_text[0]);
// do not overwrite handmade configurations from backend
$my_product->setVatId(1);
$my_product->setTemplateId(4);
}
else
{
$this->logSection('importERP', '... is updated');
}
//get prices
$price = Doctrine::getTable('ImportHelperPrice')->getPriceForImportId($line_of_text[0]);
if(!$price)
{
return;
}
$my_product->setPriceGrossEur($price->getPrice());
$my_product->Translation['de']->title = $line_of_text[2];
$my_product->Translation['de']->shortdescription = $line_of_text[3];
$my_product->Translation['de']->description =$line_of_text[3];
$my_product->setCatalogueCategory($my_cat);
$my_product->setHidden(false);
$my_product->setImportFlag(true);
$config_prices = Doctrine::getTable('ImportHelperPrice')->getPriceConfigForImportId($line_of_text[0]);
if($config_prices)
{
$price_config = '';
foreach($config_prices as $cp)
{
$discount = 100 - ($cp->getPrice() / ($price->getPrice() / 100));
if($discount == 0)
{
continue;
}
if($price_config != '')
{
$price_config .= ';';
}
$price_config .= $cp->getStartAmount() . ':' . number_format($discount, 2, ',', '');
}
$my_product->setPriceConfig($price_config);
}
//move images
$img_default = sfConfig::get('sf_root_dir'). DIRECTORY_SEPARATOR .'import_data'.DIRECTORY_SEPARATOR.'images'.DIRECTORY_SEPARATOR.$line_of_text[1].'_m.jpg';
if(file_exists($img_default))
{
rename($img_default, sfConfig::get('sf_web_dir').DIRECTORY_SEPARATOR.'products'.DIRECTORY_SEPARATOR.$line_of_text[1].'_m.jpg');
$my_product->setImageDefault($line_of_text[1].'_m.jpg');
$this->logSection('importERP', '... '.$my_product->getImageDefault().' saved');
}
else
{
$this->logSection('importERP', '... '.$img_default.' not found');
}
$img_zoom = sfConfig::get('sf_root_dir'). DIRECTORY_SEPARATOR .'import_data'.DIRECTORY_SEPARATOR.'images'.DIRECTORY_SEPARATOR.$line_of_text[1].'_gr.jpg';
if(file_exists($img_zoom))
{
rename($img_zoom, sfConfig::get('sf_web_dir').DIRECTORY_SEPARATOR.'products'.DIRECTORY_SEPARATOR.$line_of_text[1].'_zoom.jpg');
$my_product->setImageZoom($line_of_text[1].'_zoom.jpg');
$this->logSection('importERP', '... '.$my_product->getImageZoom().' saved');
}
else
{
$this->logSection('importERP', '... '.$img_zoom.' not found');
}
$img_icon = sfConfig::get('sf_root_dir'). DIRECTORY_SEPARATOR .'import_data'.DIRECTORY_SEPARATOR.'images'.DIRECTORY_SEPARATOR.$line_of_text[1].'_kl.jpg';
if(file_exists($img_icon))
{
rename($img_icon, sfConfig::get('sf_web_dir').DIRECTORY_SEPARATOR.'products'.DIRECTORY_SEPARATOR.$line_of_text[1].'_icon.jpg');
$my_product->setImageIcon($line_of_text[1].'_icon.jpg');
$this->logSection('importERP', '... '.$my_product->getImageIcon().' saved');
}
else
{
$this->logSection('importERP', '... '.$img_icon.' not found');
}
$my_product->save();
$this->logSection('importERP', 'Memory usage '.memory_get_peak_usage() / 1048576,2 .' MB');
}
private function deleteProducts()
{
//delete not mentioned products
$this->logSection('importERP', 'Delete not mentioned products');
$del_products = Doctrine::getTable('CatalogueProduct')->getAllImportFalse();
foreach($del_products as $dp)
{
$this->logSection('importERP', 'Delete '.$dp->getCode());
//delete images
$img_default = sfConfig::get('sf_web_dir').DIRECTORY_SEPARATOR.'products'.DIRECTORY_SEPARATOR.$dp->getImageDefault();
$img_zoom = sfConfig::get('sf_web_dir').DIRECTORY_SEPARATOR.'products'.DIRECTORY_SEPARATOR.$dp->getImageZoom();
$img_icon = sfConfig::get('sf_web_dir').DIRECTORY_SEPARATOR.'products'.DIRECTORY_SEPARATOR.$dp->getImageIcon();
if($dp->getImageDefault() != NULL && $dp->getImageDefault() != '' && file_exists($img_default))
{
unlink($img_default);
}
if($dp->getImageZoom() != NULL && $dp->getImageZoom() != '' && file_exists($img_zoom))
{
unlink($img_zoom);
}
if($dp->getImageIcon() != NULL && $dp->getImageIcon() != '' && file_exists($img_icon))
{
unlink($img_icon);
}
//delete product
$dp->delete();
}
}
}

The best solution would be to edit your php.ini file. Allocate:
memory_limit = 16M
Not sure if 16M is default but it should be close. Anyway, that's the amount of memory a PHP script is allowed to use. You can just set this number higher and solve the problem.
Alternatively you can write this on the top of your PHP script:
ini_set('memory_limit', '16M');
Where 16M can be changed to whatever amount of memory you wish the script to allow.

Watch out for ini_sets with values ending with 'M' - they don't work as expected. Shorthand notation works only in php.ini, appropriate info is included in the docs: http://php.net/manual/en/faq.using.php#faq.using.shorthandbytes

You should do:
...
$my_product->save();
$my_product->free();
unset($my_product);
...

Assuming your CSV is just too big for your server to handle in memory in one swoop, I would consider splitting the CSV into smaller files, which is quite a simple task with Unix commands (split, etc).
You would then execute each bitesize CSV asynchronously with your PHP script.

Related

PhpSpreadsheet - Check if file is open

I need to check if the excel file is currently open using PHPSpreadsheet.
I thought of a solution by handling this line $writer->save(file_name) into if else condition but still doesn't work.
if($writer->save(file_name){
//file is open
}else{
//file is not open
}
What else can I do to solve my problem?
I need to check if the excel file is currently open using PHPSpreadsheet.
Checking if a file is open isn't really useful, since the open/closed state could change at any time, or the failure could be caused by other filesystem problems.
What you need to do is handle the failure during file operations as:
try {
$writer->save(file_name);
}
catch (Exception $e) {
echo 'Unable to save file. Please close any other applications(s) that are using it: [", $e->getMessage(), "]\n";
}
Answered by #terry-carmen will be Incorrect in following situation:
It will still show "Resource Unavailable" error If file is exists but being used by some application and $writer->save() will try to unlink() the file.
To Overcome this situations I edited the save() function as following:
(Located at: "\vendor\phpoffice\phpspreadsheet\src\PhpSpreadsheet\Writer\Xlsx.php")
public function save($pFilename)
{
if ($this->spreadSheet !== null) {
// garbage collect
$this->spreadSheet->garbageCollect();
// If $pFilename is php://output or php://stdout, make it a temporary file...
$originalFilename = $pFilename;
if (strtolower($pFilename) == 'php://output' || strtolower($pFilename) == 'php://stdout') {
$pFilename = #tempnam(File::sysGetTempDir(), 'phpxltmp');
if ($pFilename == '') {
$pFilename = $originalFilename;
}
}
$saveDebugLog = Calculation::getInstance($this->spreadSheet)->getDebugLog()->getWriteDebugLog();
Calculation::getInstance($this->spreadSheet)->getDebugLog()->setWriteDebugLog(false);
$saveDateReturnType = Functions::getReturnDateType();
Functions::setReturnDateType(Functions::RETURNDATE_EXCEL);
// Create string lookup table
$this->stringTable = [];
for ($i = 0; $i < $this->spreadSheet->getSheetCount(); ++$i) {
$this->stringTable = $this->getWriterPart('StringTable')->createStringTable($this->spreadSheet->getSheet($i), $this->stringTable);
}
// Create styles dictionaries
$this->styleHashTable->addFromSource($this->getWriterPart('Style')->allStyles($this->spreadSheet));
$this->stylesConditionalHashTable->addFromSource($this->getWriterPart('Style')->allConditionalStyles($this->spreadSheet));
$this->fillHashTable->addFromSource($this->getWriterPart('Style')->allFills($this->spreadSheet));
$this->fontHashTable->addFromSource($this->getWriterPart('Style')->allFonts($this->spreadSheet));
$this->bordersHashTable->addFromSource($this->getWriterPart('Style')->allBorders($this->spreadSheet));
$this->numFmtHashTable->addFromSource($this->getWriterPart('Style')->allNumberFormats($this->spreadSheet));
// Create drawing dictionary
$this->drawingHashTable->addFromSource($this->getWriterPart('Drawing')->allDrawings($this->spreadSheet));
$zip = new ZipArchive();
if (file_exists($pFilename)) {
// Added by muhammad.begawala#gmail.com
// '#' will stop displaying "Resource Unavailable" error because of file is open some where.
// 'unlink($pFilename) !== true' will check if file is deleted successfully.
// Throwing exception so that we can handle error easily instead of displaying to users.
if (#unlink($pFilename) !== true) {
throw new WriterException('Could not delete file: ' . $pFilename . ' Please close all applications that are using it.');
}
}
// Try opening the ZIP file
if ($zip->open($pFilename, ZipArchive::OVERWRITE) !== true) {
if ($zip->open($pFilename, ZipArchive::CREATE) !== true) {
throw new WriterException('Could not open ' . $pFilename . ' for writing.');
}
}
// Add [Content_Types].xml to ZIP file
$zip->addFromString('[Content_Types].xml', $this->getWriterPart('ContentTypes')->writeContentTypes($this->spreadSheet, $this->includeCharts));
//if hasMacros, add the vbaProject.bin file, Certificate file(if exists)
if ($this->spreadSheet->hasMacros()) {
$macrosCode = $this->spreadSheet->getMacrosCode();
if ($macrosCode !== null) {
// we have the code ?
$zip->addFromString('xl/vbaProject.bin', $macrosCode); //allways in 'xl', allways named vbaProject.bin
if ($this->spreadSheet->hasMacrosCertificate()) {
//signed macros ?
// Yes : add the certificate file and the related rels file
$zip->addFromString('xl/vbaProjectSignature.bin', $this->spreadSheet->getMacrosCertificate());
$zip->addFromString('xl/_rels/vbaProject.bin.rels', $this->getWriterPart('RelsVBA')->writeVBARelationships($this->spreadSheet));
}
}
}
//a custom UI in this workbook ? add it ("base" xml and additional objects (pictures) and rels)
if ($this->spreadSheet->hasRibbon()) {
$tmpRibbonTarget = $this->spreadSheet->getRibbonXMLData('target');
$zip->addFromString($tmpRibbonTarget, $this->spreadSheet->getRibbonXMLData('data'));
if ($this->spreadSheet->hasRibbonBinObjects()) {
$tmpRootPath = dirname($tmpRibbonTarget) . '/';
$ribbonBinObjects = $this->spreadSheet->getRibbonBinObjects('data'); //the files to write
foreach ($ribbonBinObjects as $aPath => $aContent) {
$zip->addFromString($tmpRootPath . $aPath, $aContent);
}
//the rels for files
$zip->addFromString($tmpRootPath . '_rels/' . basename($tmpRibbonTarget) . '.rels', $this->getWriterPart('RelsRibbonObjects')->writeRibbonRelationships($this->spreadSheet));
}
}
// Add relationships to ZIP file
$zip->addFromString('_rels/.rels', $this->getWriterPart('Rels')->writeRelationships($this->spreadSheet));
$zip->addFromString('xl/_rels/workbook.xml.rels', $this->getWriterPart('Rels')->writeWorkbookRelationships($this->spreadSheet));
// Add document properties to ZIP file
$zip->addFromString('docProps/app.xml', $this->getWriterPart('DocProps')->writeDocPropsApp($this->spreadSheet));
$zip->addFromString('docProps/core.xml', $this->getWriterPart('DocProps')->writeDocPropsCore($this->spreadSheet));
$customPropertiesPart = $this->getWriterPart('DocProps')->writeDocPropsCustom($this->spreadSheet);
if ($customPropertiesPart !== null) {
$zip->addFromString('docProps/custom.xml', $customPropertiesPart);
}
// Add theme to ZIP file
$zip->addFromString('xl/theme/theme1.xml', $this->getWriterPart('Theme')->writeTheme($this->spreadSheet));
// Add string table to ZIP file
$zip->addFromString('xl/sharedStrings.xml', $this->getWriterPart('StringTable')->writeStringTable($this->stringTable));
// Add styles to ZIP file
$zip->addFromString('xl/styles.xml', $this->getWriterPart('Style')->writeStyles($this->spreadSheet));
// Add workbook to ZIP file
$zip->addFromString('xl/workbook.xml', $this->getWriterPart('Workbook')->writeWorkbook($this->spreadSheet, $this->preCalculateFormulas));
$chartCount = 0;
// Add worksheets
for ($i = 0; $i < $this->spreadSheet->getSheetCount(); ++$i) {
$zip->addFromString('xl/worksheets/sheet' . ($i + 1) . '.xml', $this->getWriterPart('Worksheet')->writeWorksheet($this->spreadSheet->getSheet($i), $this->stringTable, $this->includeCharts));
if ($this->includeCharts) {
$charts = $this->spreadSheet->getSheet($i)->getChartCollection();
if (count($charts) > 0) {
foreach ($charts as $chart) {
$zip->addFromString('xl/charts/chart' . ($chartCount + 1) . '.xml', $this->getWriterPart('Chart')->writeChart($chart, $this->preCalculateFormulas));
++$chartCount;
}
}
}
}
$chartRef1 = 0;
// Add worksheet relationships (drawings, ...)
for ($i = 0; $i < $this->spreadSheet->getSheetCount(); ++$i) {
// Add relationships
$zip->addFromString('xl/worksheets/_rels/sheet' . ($i + 1) . '.xml.rels', $this->getWriterPart('Rels')->writeWorksheetRelationships($this->spreadSheet->getSheet($i), ($i + 1), $this->includeCharts));
// Add unparsedLoadedData
$sheetCodeName = $this->spreadSheet->getSheet($i)->getCodeName();
$unparsedLoadedData = $this->spreadSheet->getUnparsedLoadedData();
if (isset($unparsedLoadedData['sheets'][$sheetCodeName]['ctrlProps'])) {
foreach ($unparsedLoadedData['sheets'][$sheetCodeName]['ctrlProps'] as $ctrlProp) {
$zip->addFromString($ctrlProp['filePath'], $ctrlProp['content']);
}
}
if (isset($unparsedLoadedData['sheets'][$sheetCodeName]['printerSettings'])) {
foreach ($unparsedLoadedData['sheets'][$sheetCodeName]['printerSettings'] as $ctrlProp) {
$zip->addFromString($ctrlProp['filePath'], $ctrlProp['content']);
}
}
$drawings = $this->spreadSheet->getSheet($i)->getDrawingCollection();
$drawingCount = count($drawings);
if ($this->includeCharts) {
$chartCount = $this->spreadSheet->getSheet($i)->getChartCount();
}
// Add drawing and image relationship parts
if (($drawingCount > 0) || ($chartCount > 0)) {
// Drawing relationships
$zip->addFromString('xl/drawings/_rels/drawing' . ($i + 1) . '.xml.rels', $this->getWriterPart('Rels')->writeDrawingRelationships($this->spreadSheet->getSheet($i), $chartRef1, $this->includeCharts));
// Drawings
$zip->addFromString('xl/drawings/drawing' . ($i + 1) . '.xml', $this->getWriterPart('Drawing')->writeDrawings($this->spreadSheet->getSheet($i), $this->includeCharts));
} elseif (isset($unparsedLoadedData['sheets'][$sheetCodeName]['drawingAlternateContents'])) {
// Drawings
$zip->addFromString('xl/drawings/drawing' . ($i + 1) . '.xml', $this->getWriterPart('Drawing')->writeDrawings($this->spreadSheet->getSheet($i), $this->includeCharts));
}
// Add comment relationship parts
if (count($this->spreadSheet->getSheet($i)->getComments()) > 0) {
// VML Comments
$zip->addFromString('xl/drawings/vmlDrawing' . ($i + 1) . '.vml', $this->getWriterPart('Comments')->writeVMLComments($this->spreadSheet->getSheet($i)));
// Comments
$zip->addFromString('xl/comments' . ($i + 1) . '.xml', $this->getWriterPart('Comments')->writeComments($this->spreadSheet->getSheet($i)));
}
// Add unparsed relationship parts
if (isset($unparsedLoadedData['sheets'][$this->spreadSheet->getSheet($i)->getCodeName()]['vmlDrawings'])) {
foreach ($unparsedLoadedData['sheets'][$this->spreadSheet->getSheet($i)->getCodeName()]['vmlDrawings'] as $vmlDrawing) {
$zip->addFromString($vmlDrawing['filePath'], $vmlDrawing['content']);
}
}
// Add header/footer relationship parts
if (count($this->spreadSheet->getSheet($i)->getHeaderFooter()->getImages()) > 0) {
// VML Drawings
$zip->addFromString('xl/drawings/vmlDrawingHF' . ($i + 1) . '.vml', $this->getWriterPart('Drawing')->writeVMLHeaderFooterImages($this->spreadSheet->getSheet($i)));
// VML Drawing relationships
$zip->addFromString('xl/drawings/_rels/vmlDrawingHF' . ($i + 1) . '.vml.rels', $this->getWriterPart('Rels')->writeHeaderFooterDrawingRelationships($this->spreadSheet->getSheet($i)));
// Media
foreach ($this->spreadSheet->getSheet($i)->getHeaderFooter()->getImages() as $image) {
$zip->addFromString('xl/media/' . $image->getIndexedFilename(), file_get_contents($image->getPath()));
}
}
}
// Add media
for ($i = 0; $i < $this->getDrawingHashTable()->count(); ++$i) {
if ($this->getDrawingHashTable()->getByIndex($i) instanceof WorksheetDrawing) {
$imageContents = null;
$imagePath = $this->getDrawingHashTable()->getByIndex($i)->getPath();
if (strpos($imagePath, 'zip://') !== false) {
$imagePath = substr($imagePath, 6);
$imagePathSplitted = explode('#', $imagePath);
$imageZip = new ZipArchive();
$imageZip->open($imagePathSplitted[0]);
$imageContents = $imageZip->getFromName($imagePathSplitted[1]);
$imageZip->close();
unset($imageZip);
} else {
$imageContents = file_get_contents($imagePath);
}
$zip->addFromString('xl/media/' . str_replace(' ', '_', $this->getDrawingHashTable()->getByIndex($i)->getIndexedFilename()), $imageContents);
} elseif ($this->getDrawingHashTable()->getByIndex($i) instanceof MemoryDrawing) {
ob_start();
call_user_func(
$this->getDrawingHashTable()->getByIndex($i)->getRenderingFunction(),
$this->getDrawingHashTable()->getByIndex($i)->getImageResource()
);
$imageContents = ob_get_contents();
ob_end_clean();
$zip->addFromString('xl/media/' . str_replace(' ', '_', $this->getDrawingHashTable()->getByIndex($i)->getIndexedFilename()), $imageContents);
}
}
Functions::setReturnDateType($saveDateReturnType);
Calculation::getInstance($this->spreadSheet)->getDebugLog()->setWriteDebugLog($saveDebugLog);
// Close file
if ( #$zip->close() === false ) { // updated by muhammad.begawala#gmail.com
throw new WriterException("Could not close zip file $pFilename.");
}
// If a temporary file was used, copy it to the correct file stream
if ($originalFilename != $pFilename) {
if (copy($pFilename, $originalFilename) === false) {
throw new WriterException("Could not copy temporary zip file $pFilename to $originalFilename.");
}
#unlink($pFilename);
}
return true;
// Return True to make sure that file is created successfully with no ExceptionsAdded by muhammad.begawala#gmail.com
} else {
throw new WriterException('PhpSpreadsheet object unassigned.');
}
}
Major Changes:
1) Handling "Resource Unavailable" error by unlink() as Exception using try catch so that It doesn't show error when file is being used by some applications when we tries to delete it using unlink.
if (file_exists($pFilename)) {
// Added by muhammad.begawala#gmail.com
// '#' will stop displaying "Resource Unavailable" error because of file is open some where.
// 'unlink($pFilename) !== true' will check if file is deleted successfully.
// Throwing exception so that we can handle error easily instead of displaying to users.
if (#unlink($pFilename) !== true) {
throw new WriterException('Could not delete file: ' . $pFilename . ' Please close all applications that are using it.');
}
}
2) $writer->save('hello world.xlsx') will return TRUE if file is successfully created else throw Exception.
Usage:
try {
$writer->save('hello world.xlsx');
echo 'File Created';
}
catch (Exception $e) {
echo $e->getMessage(); // Will print Exception thrown by save()
}

Error import CSV file Crontab

I created a script to import a CSV file. When I run it by hand with the php command on the server the script runs without problems. On the other hand when the crontab execute it there is an error:
SPLFILEOBJECT::__CONSTRUCT(IMPORTS/STOCK_EXPRESS_FR.CSV): FAILED TO
OPEN STREAM: NO SUCH FILE OR DIRECTORY .
Here is my import script.
<?php
require(dirname(__FILE__) . '/config/config.inc.php');
$dir_fichier = 'IMPORTS/STOCK_EXPRESS_FR.csv';
//error_reporting(E_ALL);
ini_set('display_errors', 0);
tntProduct($dir_fichier);
function tntProduct($dir_fichier)
{
$errors = [];
try{
$csv = new SplFileObject($dir_fichier);
$csv->setFlags(SplFileObject::READ_CSV);
$csv->setCsvControl(';');
} catch (Exception $exception) {
$errors[] = $exception->getMessage();
}
$nbProducts = 0;
$nbProductsSuccess = 0;
foreach ($csv as $ligne) {
if ($ligne[1] === '0') {
$result = getIdsProducts($ligne[0]);
if (!empty($result)) {
foreach ($result as $key => $item) {
$nbProducts++;
try {
setCarrier($item['id_product']);
$nbProductsSuccess++;
}catch (Exception $exception) {
$errors[] = $exception->getMessage();
}
}
}
}
}
if (count($errors)>0) {
sendMail($errors);
} else {
sendMail($nbProducts);
}
if (file_exists ($dir_fichier)) {
unlink($dir_fichier);
}
}
function getIdsProducts($ref)
{
$sql = Db::getInstance()->executeS('
SELECT p.id_product
FROM ' . _DB_PREFIX_ . 'product p
WHERE p.reference = ' . '"' . $ref . '"');
return $sql;
}
function setCarrier($productId)
{
$shop = 1;
$carriersFR = [
0 => 1,
1 => 72,
2 => 87
];
$products = new Product((int)$productId, false, 1, $shop);
$products->setCarriers($carriersFR);
}
function sendMail($result)
{
$data['{message}'] = $result;
Mail::Send(
1,
'tnt_fr',
'Mise à jour TNT France',
$data,
'test#test.fr',
'test',
null,
null,
null,
true,
_PS_MAIL_DIR_,
false,
1
);
}
Do you have an idea of ​​the problem ? Thank you for your help
In crontab run the script, is not be in the folder, so you need to write full path or correct relative path.

Erro 406 (Not Acceptable) jquery file upload Deleting Files

I am having trouble deleting the files with jquery fileupload . by clicking delete the error happens , do not delete the file . Error message:
upload/server/php/index.php?file=xxxx.png 406 (Not Acceptable)
Hpierce This is the code to which it refers
public function delete($print_response = true){
$file_names = $this->get_file_names_params();
if (empty($file_names)) {
$file_names = array($this->get_file_name_param());
}
$response = array();
foreach($file_names as $file_name) {
$file_path = $this->get_upload_path($file_name);
$success = is_file($file_path) && $file_name[0] !== '.' && unlink($file_path);
if ($success) {
foreach($this->options['image_versions'] as $version => $options) {
if (!empty($version)) {
$file = $this->get_upload_path($file_name, $version);
if (is_file($file)) {
unlink($file);
}
}
}
}
$response[$file_name] = $success;
}
return $this->generate_response($response, $print_response);
}
I have the same problem

Recursive function won't return array from another function; Am I missing something?

Consider the following: I am using gzipped .cvs reports downloaded through an API to render data live (constructTable). First I check to see if the file has been downloaded, then if it's complete (more thorough check should be implemented, just don't know how yet). If everything's okay, it should read the file and turn it into an array - which I return to the recursive function which in turn returns it to my constructTable function. But the array won't return from the checkReport function to the constructTable. What am I doing wrong?
function fileToArray($filePath){
$file = fopen($filePath,'rb');
$gzipcsv = fread($file, filesize($filePath));
fclose($file);
$ungzipcsv = gzdecode($gzipcsv);
return parse_csv($ungzipcsv);
}
function checkReport($filePath,$queryStr,$status=''){
if($status!='ok'){
if(!file_exists($filePath)){
if($status!='creating_report'){
DownloadReport($_SESSION['currentUser'],$filePath,$queryStr);
$status='creating_report';
} else {
usleep(100000);
$status='downloading_report';
}
} else {
if(filesize($filePath)!=0){
$fs = filesize($filePath);
usleep(100000);
clearstatcache(TRUE, $filePath);
if($fs==filesize($filePath)){
$status='ok';
} else {
$status='downloading_report';
}
} else {
$status='zero_filesize';
}
}
checkReport($filePath,$queryStr,$status);
} else {
return fileToArray($filePath);
}
}
function constructTable($user, $fields, $dataType, $reportName, $conditionItem, $conditionId, $dateRange) {
$filePath = dirname(dirname(__FILE__)) . '/csv/'.$GLOBALS['customer'].'__'.$dataType.'__'.$reportName.'.csv.gz';
$queryStr = 'SELECT '.implode(',',$fields);
$queryStr .= ' FROM '.$reportName;
$queryStr .= '';
if($conditionId!='') $queryStr .= ' WHERE '.$conditionItem.' = '.$conditionId;
$queryStr .= ' DURING '.$dateRange;
$csv_array = NULL;
$i = 0;
while(!$csv_array){
if($i++>2){
break;
}
$csv_array = checkReport($filePath,$queryStr);
var_dump(checkReport($filePath,$queryStr));
}

Call to undefined method Config::getConfig()

I'm testing the Flexpaper plugin on Windows XP running with XAMP, the issue is that it doesn't shows the pdf's, checking the php error log it says:
PHP Fatal error: Call to undefined method Config::getConfig() in
C:\xampp\htdocs\PDFViewer\php\services\view.php on line 24
The folder structure is: (omitting irrelevant files)
htdocs/
|->PDFViewer/
|->php/
|->admin_files/
|->config/
|->config.ini.win.php
|->lib/
|->common.php
|->pdf2json_php5.php
|->pdf2swf_php5.php
|->config.php
|->services/
|->view.php
Snippet of code of view.php
require_once("../lib/common.php");
require_once("../lib/pdf2swf_php5.php");
require_once("../lib/swfrender_php5.php");
require_once("../lib/pdf2json_php5.php");
Snippet of code of pdf2json_php5.php
require_once("config.php");
require_once("common.php");
Snippet of code of pdf2swf_php5.php
require_once("config.php");
require_once("common.php");
Snippet of code of swfrender_php5.php
require_once("config.php");
require_once("common.php");
And before you ask, yes, config.php do have the getConfig method
Edit: Added the config.php
<?php date_default_timezone_set('America/New_York'); ?>
<?php
class Config{
protected $config;
public function __construct()
{
if (!defined('ROOT')) {
define('ROOT', dirname(dirname(dirname(__FILE__))));
}
if (!defined('APP_DIR')) {
define('APP_DIR', basename(dirname(dirname(__FILE__))));
}
if( PHP_OS == "WIN32" || PHP_OS == "WINNT" )
$this->config = parse_ini_file($this->getConfigFilename());
else
$this->config = parse_ini_file($this->getConfigFilename());
}
public function getConfigDir(){
if( PHP_OS == "WIN32" || PHP_OS == "WINNT" )
return dirname(__FILE__) . '\\..\\config';
else
return dirname(__FILE__) . '/../config';
}
public function getConfigs(){
return $this->config;
}
public function getConfig($key = null)
{
if($key !== null)
{
if(isset($this->config[$key]))
{
return $this->config[$key];
}
else
{
return null;
}
}
else
{
return $this->config;
}
}
public function setConfig($config)
{
$this->config = $config;
}
public function getDocUrl(){
return "<br/><br/>Click <a href='http://flexpaper.devaldi.com/docs_php.jsp'>here</a> for more information on configuring FlexPaper with PHP";
}
public function getConfigFilename(){
if( PHP_OS == "WIN32" || PHP_OS == "WINNT" )
return ROOT . '\\' . APP_DIR . '\\config\\config.ini.win.php';
else
return ROOT . '/' . APP_DIR . '/config/config.ini.nix.php';
}
public function saveConfig($array){
$this->write_php_ini($array,$this->getConfigFilename());
}
function write_php_ini($array, $file)
{
$res = array();
foreach($array as $key => $val)
{
if(is_array($val))
{
$res[] = "[$key]";
foreach($val as $skey => $sval) {
$sval = str_replace("\"","\\\"",$sval);
$res[] = "$skey = ".(is_numeric($sval) ? $sval : '"'.$sval.'"');
}
}
else {
$val = str_replace("\"","\\\"",$val);
$res[] = "$key = ".(is_numeric($val) ? $val : '"'.$val.'"');
}
}
$this->safefilerewrite($file, implode("\r\n", $res));
}
function safefilerewrite($fileName, $dataToSave)
{
$dataToSave = "; <?php exit; ?> DO NOT REMOVE THIS LINE\r\n" . $dataToSave;
if ($fp = fopen($fileName, 'w'))
{
$startTime = microtime();
do
{
$canWrite = flock($fp, LOCK_EX);
// If lock not obtained sleep for 0 - 100 milliseconds, to avoid collision and CPU load
if(!$canWrite) usleep(round(rand(0, 100)*1000));
} while ((!$canWrite)and((microtime()-$startTime) < 1000));
//file was locked so now we can store information
if ($canWrite)
{ fwrite($fp, $dataToSave);
flock($fp, LOCK_UN);
}
fclose($fp);
}else{
throw new Exception('Cant write to config ' . $fileName);
}
}
}
Modify the code snippet of view.php into:
$ds = DIRECTORY_SEPARATOR;
require_once("..{$ds}lib{$ds}common.php");
require_once("..{$ds}lib{$ds}pdf2swf_php5.php");
require_once("..{$ds}lib{$ds}swfrender_php5.php");
require_once("..{$ds}lib{$ds}pdf2json_php5.php");
Looks like I've made it work after adding C:/xampp/htdocs to the include_path variable in php.ini, and then just modified the require_once functions.
require_once section in View.php looks like:
require_once("PDFViewer/php/lib/common.php");
require_once("PDFViewer/php/lib/pdf2swf_php5.php");
require_once("PDFViewer/php/lib/swfrender_php5.php");
require_once("PDFViewer/php/lib/pdf2json_php5.php");
And the same for pdf2swf_php5.php, swfrender_php5.php and pdf2json_php5.php.

Categories