im trying to create a php class that will transform an ini in to an array ie:
example.ini...
[helloworld]
testing=1234
the array should look like:
array {
"helloworld" = array {
"testing" = "1234"
}
}
my code fo far is this:
<?php
require_once "UseFullFunctions.inc.php";
class INI {
protected $Keys = array();
protected $Values = array();
public function __construct($FileName) {
if (!file_exists($FileName)){
throwException('File not found',$FileName);
}
$File = fopen($FileName, 'r');
$isIn = "";
while (($line = fgets($File)) !== false) {
if(!startswith($line,'#')){ // checks if the line is a comment
if(startswith($line,'[')){
$isIn = trim($line,'[]');
$this->Keys[$isIn] = '';
$this->Values[$isIn] = array();
} else {
if ($isIn != ""){
$vars = explode("=",$line);
$this->Values[$isIn][$vars[0]] = $vars[1];
}
}
}
}
var_dump($this->Values);
if (!feof($File)) {
echo "Error: unexpected fgets() fail\n";
}
fclose($File);
}
public function getValues() {
return $this->Values;
}
}
?>
the other functions(starts with, throwexception) ive already tested and work fine but it still returns a blank array i think its stuffing up just after it checks if the line is a comment but it doesnt come up with an error messages so i cant be sure
just incase here is my starts with code:
function throwException($message = null,$code = null) {
throw new Exception($message,$code);
}
function startsWith($haystack, $needle)
{
return !strncmp($haystack, $needle, strlen($needle));
}
Take a look at parse_ini_file
http://uk3.php.net/parse_ini_file
Related
Here's the whole script.php:
require_once('../app/Mage.php'); Mage::init();
$fbn = ($_GET['fbn']) ? trim(htmlencode($_GET['fbn'])) : null;
if (is_null($fbn)) die("specify filebasename in url (?fbn= )");
$file = __DIR__."/csv/{$fbn}.csv"; echo $file; var_dump($_GET);
class UpdateProductGallerySelects
{
public function __construct($file, $num = 0)
{
if (!file_exists($file)) die('no good file');
$csv = array_map('str_getcsv', file($file));
array_walk($csv, function(&$a) use ($csv) {
$a = array_combine($csv[0], $a);
}); array_shift($csv);
foreach ($csv as $row) $this->updateProduct($row);
}
private function updateProduct($r)
{
$p = null; print_r($r);
$p = Mage::getModel('catalog/product')->load($r['sku'], 'sku');
$g = $p->getMediaGalleryImages('images');
$ct = count($g); echo $p->getName()." {{$ct}}\n";
}
}
$set = new UpdateProductGallerySelects($file, 10);
This runs up to the first die(), apparently, which does print if $fbn is null.
Please tell me what's wrong.
You must check your $_GET['fbn'] as it seems you are not getting anything in this variable. You must pass some value in it and then check.
I'm having a headache trying to figure this out.
My folder structure is as follows:
index.php
helpers:
API.php
helpers.php
assets:
products.csv
debug:
debug_info.txt
My index file looks as follows:
<?php
require_once 'helpers/API.php';
file_put_contents('debug/debug_info.txt', "New request started");
if (in_array($_GET['action'],array('insertOrder','updateOrder'))){
$date = date(DATE_RFC2822);
$api = new API();
file_put_contents('debug/debug_info.txt', "New: {$_GET['action']} at {$date}\n", FILE_APPEND | LOCK_EX);
file_put_contents('debug/debug_info.txt', "This is the product " . $api->getOrder());
}
API.php
<?php
class API {
private $order;
private $product_table;
function __construct(){
$this->order = $this->setOrder();
$this->product_table = $this->setProductTable();
}
public function setOrder(){return $this->readJSON();}
public function setProductTable(){return $this->readProductsCSV(__DIR__ . '/../assets/products.csv');}
public function getOrder(){return $this->order;}
public function getProductsTable(){return $this->product_table;}
private function readJSON(){
$stream = fopen('php://input', 'rb');
$json = stream_get_contents($stream);
fclose($stream);
return print_r(json_decode($json, true), true);
}
private function readProductsCSV($csv = '', $delimiter = ','){
if (!file_exists($csv) || !is_readable($csv)){
return "Someone f*cked up -_-";
}
$header = NULL;
$data = array();
if (($handle = fopen($csv, 'r')) !== false){
while (($row = fgetcsv($csv, 100, $delimiter)) !== false){
if (!$header)
$header = $row;
else if($row[0] != ''){
$row = array_merge(array_slice($row,0,2), array_filter(array_slice($row, 2)));
$sku = $row[0];
$data[$sku]['productCode'] = $row[1];
$data[$sku]['Description'] = $row[2];
}
}
fclose($handle);
}
array_change_key_case($data, CASE_LOWER);
return print_r($data, true);
}
}
When I use file_put_contents('debug/debug_info.txt', $api->getOrder()); I get the data correctly ( I have to comment all the product_table parts for it to work tho ).
But I can't get the CSV file no matter what I do.
I've ran file_exists() && is_readable ( and they passed ) but still nothing.
If I declare the function readProductsCSV in the index.php it works.. but it seems using it as a method bugs everything.
Could someone please help me?
Logic bugs:
if (($handle = fopen($csv, 'r')) !== false){
^---your csv file handle
while (($row = fgetcsv($csv, 100, $delimiter)) !== false){
^---your csv filename, which SHOULD be the handle
Since you're trying to use a string as a filehandle, you get a boolean false back from fgetcsv() for failure, that false terminates the while loop, and $data stays an empty array.
When using chained functions, is there a way to determine if the current call is the last in the chain?
For example:
$oObject->first()->second()->third();
I want to check in first, second and third if the call is the last in the chain so it saves me to write a result-like function to always add to the chain. In this example the check should result true in third.
No, not in any way that's sane or maintainable.
You'll have to add a done() method or similar.
As far as i know it's impossible, i'd suggest to use finishing method like this:
$oObject->first()
->second()
->third()
->end(); // like this
If you want to execute a function on the last chain (without addional exec or done on the chain).
The code below will obtain the full chain from the source code and return the data after the last chain.
<?php
$abc = new Methods;
echo($abc->minus(12)->plus(32)); // output: -12+32
echo(
$abc->plus(84)
->minus(63)
); // output: +84-63
class Methods{
private $data = '';
private $chains = false;
public function minus($val){
$this->data .= '-'.$val;
return $this->exec('minus');
}
public function plus($val){
$this->data .= '+'.$val;
return $this->exec('plus');
}
private function exec($from){
// Check if this is the first chain
if($this->chains === false){
$this->getChains();
}
// Remove the first chain as it's
// already being called
if($this->chains[0] === $from){
array_shift($this->chains);
}
else
die("Can't parse your chain");
// Check if this is the last chain
if(count($this->chains) === 0){
$copy = $this->data;
// Clear data
$this->chains = false;
$this->data = '';
return $copy;
}
// If not then continue the chain
return $this;
}
private function getChains(){
$temp = debug_backtrace(DEBUG_BACKTRACE_IGNORE_ARGS);
// Find out who called the function
for ($i=0; $i < count($temp); $i++) {
if($temp[$i]['function'] === 'exec'){
$temp = $temp[$i + 1];
break;
}
}
// Prepare variable
$obtained = '';
$current = 1;
// Open that source and find the chain
$handle = fopen($temp['file'], "r");
if(!$handle) return false;
while(($text = fgets($handle)) !== false){
if($current >= $temp['line']){
$obtained .= $text;
// Find break
if(strrpos($text, ';') !== false)
break;
}
$current++;
}
fclose($handle);
preg_match_all('/>(\w.*?)\(/', $obtained, $matches);
$this->chains = $matches[1];
return true;
}
}
i am actually working on this mentioned title. player show the list, its generating perfectly. but i am no where to make it actually play that file. i must be wrong some where.
i need advise fox. (ahh if i can attach the files.)
my class
class DecodDir
{
function getFiles($directory)
{
$all_files = array();
$handler = opendir($directory);
while($files=readdir($handler))
{
if($files!="." && $files!="..")
{
$all_files[]= $files;
}
}
closedir($handler);
return $all_files;
}
}
################# file where i am using this class *###############
<?php
include("decoddir.php");
$obj = new DecodDir();
$results = $obj->getFiles("mp3");
$total = count($results);
$string = "";
for($i=0; $i<$total; $i++){
$string .="
{
name:'$results[$i]',
mp3:'mp3/$results[$i]',
ogg:'$results[$i]'
},
";
}
?>
// its at the top of that html file (ofcorse with the php ext)
and below, this is where it is generating the playlist
var audioPlaylist = new Playlist("2", [
<?php echo $string; ?>
],
http://www.jplayer.org/latest/demo-02/ (the link from where i get jplayer) you can see the audio player with playlist.
(actually i don't know hot format the code in here stackoverflow)
thanks
Rafay
I have taken the liberty of re-factoring the code a bit for you. I don't know exactly what you are trying to do, but it will help to have the beginnings of a better class on your side.
<?php
class DecodDir
{
private
$directory,
$files;
public function __construct( $directory = null )
{
if ( ! is_null($directory) )
{
$this->setDirectory( $directory );
}
}
public function setDirectory( $directory )
{
$this->directory = $directory;
$this->files = null;
// TODO put some validation in here;
return $this;
}
public function getDirectory()
{
if ( is_null($this->directory) )
{
$this->directory = './';
}
return $this->directory;
}
private function getFiles()
{
if ( is_null($this->files) )
{
$this->files = array();
$handler = opendir( $this->getDirectory() );
while($files=readdir($handler))
{
if($files!="." && $files!="..")
{
$this->files[]= $files;
}
}
closedir($handler);
}
return $this->files;
}
public function getJson()
{
$list = array();
foreach ( $this->getFiles() as $filename )
{
$item = new stdClass();
$item->name = $filename;
$item->mp3 = "mp3/{$filename}";
$item->ogg = $filename;
$list[] = $item;
}
$json = json_encode( $list );
return $json;
}
public function countFiles()
{
return sizeof( $this->getFiles() );
}
}
$obj = new DecodDir( 'mp3' );
echo $obj->getJson();
I wrote the code at the following site to do what you are trying to do, I think:
http://jplaylister.yaheard.us/
Sadly, it doesn't currently collapse a song stored in multiple formats (mysong1.mp3, mysong1.ogg) into one playlist item, but otherwise it is pretty feature-complete and has lots of customizable options.
Hope this helps!
Can i parse a plist file with php and kind of get it into an array, like the $_POST[''] so i could call $_POST['body'] and get the string that has the <key> body ?
CFPropertyList - A PHP Implementation Of Apple's plist (PropertyList)
Googling for "php plist parser" turned up this blog post that seems to be able to do what you are asking for.
Took a look at some of the libraries out there but they have external requirements and seem overkill. Here's a function that simply puts the data in to associative arrays. This worked on a couple of exported itunes plist files I tried.
// pass in the full plist file contents
function parse_plist($plist) {
$result = false;
$depth = [];
$key = false;
$lines = explode("\n", $plist);
foreach ($lines as $line) {
$line = trim($line);
if ($line) {
if ($line == '<dict>') {
if ($result) {
if ($key) {
// adding a new dictionary, the line above this one should've had the key
$depth[count($depth) - 1][$key] = [];
$depth[] =& $depth[count($depth) - 1][$key];
$key = false;
} else {
// adding a dictionary to an array
$depth[] = [];
}
} else {
// starting the first dictionary which doesn't have a key
$result = [];
$depth[] =& $result;
}
} else if ($line == '</dict>' || $line == '</array>') {
array_pop($depth);
} else if ($line == '<array>') {
$depth[] = [];
} else if (preg_match('/^\<key\>(.+)\<\/key\>\<.+\>(.+)\<\/.+\>$/', $line, $matches)) {
// <key>Major Version</key><integer>1</integer>
$depth[count($depth) - 1][$matches[1]] = $matches[2];
} else if (preg_match('/^\<key\>(.+)\<\/key\>\<(true|false)\/\>$/', $line, $matches)) {
// <key>Show Content Ratings</key><true/>
$depth[count($depth) - 1][$matches[1]] = ($matches[2] == 'true' ? 1 : 0);
} else if (preg_match('/^\<key\>(.+)\<\/key\>$/', $line, $matches)) {
// <key>1917</key>
$key = $matches[1];
}
}
}
return $result;
}