i am using the function write_php_ini to write files
see the accepted answer with around 40 upvotes at:
create ini file, write values in PHP
originally i was copying from here:
How to read and write to an ini file with PHP
from the answer that is not accepted, because they looked so similar
the problem is, what if 2 process write to it at the same time? (that is, the second post seems to handle it, whereas the first one does not)
how to avoid this problem?
this is the code:
public static function write_ini_file($assoc_arr, $path, $has_sections=FALSE) {
$content = "";
if ($has_sections) {
foreach ($assoc_arr as $key=>$elem) {
$content .= "[".$key."]\n";
foreach ($elem as $key2=>$elem2) {
if(is_array($elem2))
{
for($i=0;$i<count($elem2);$i++)
{
$content .= $key2."[] = \"".$elem2[$i]."\"\n";
}
}
else if($elem2=="") $content .= $key2." = \n";
else $content .= $key2." = \"".$elem2."\"\n";
}
}
}
else {
foreach ($assoc_arr as $key=>$elem) {
if(is_array($elem))
{
for($i=0;$i<count($elem);$i++)
{
$content .= $key."[] = \"".$elem[$i]."\"\n";
}
}
else if($elem=="") $content .= $key." = \n";
else $content .= $key." = \"".$elem."\"\n";
}
}
if (!$handle = fopen($path, 'w')) {
return false;
}
$success = fwrite($handle, $content);
fclose($handle);
return $success;
}
Related
Currently working on something where i need to add the UTM tag to all links, got 1/2 minor issues i cant figure out
This is the code im am using, the issue is if a link got a parameter like ?test=test then this refuses to add the utm tags.
The other issue is a minor issue that im not sure would make sence to change, insted of me having to add a url, it could be neat if it added utm tags to ALL a href's by default with out knowing the domain name.
Hope someone can help me out and push me in the right direction.
$url_modifier_domain = preg_quote('add-link.com');
$html_text = preg_replace_callback(
'#((?:https?:)?//'.$url_modifier_domain.'(/[^\'"\#]*)?)(?=[\'"\#])#i',
function($matches){
$url_modifier = 'utm=some&medium=stuff';
if (!isset($matches[2])) return $matches[1]."/?$url_modifier";
$q = strpos($matches[2],'?');
if ($q===false) return $matches[1]."?$url_modifier";
if ($q==strlen($matches[2])-1) return $matches[1].$url_modifier;
return $matches[1]."&$url_modifier";
},
$html);
once detected the urls you can use parse_url() and parse_str() to elaborate the url, add utm and medium and rebuild it without caring too much about the content of the get parameters or the hash:
$url_modifier_domain = preg_quote('add-link.com');
$html_text = preg_replace_callback(
'#((?:https?:)?//'.$url_modifier_domain.'(/[^\'"\#]*)?)(?=[\'"\#])#i',
function ($matches) {
$link = $matches[0];
if (strpos($link, '#') !== false) {
list($link, $hash) = explode('#', $link);
}
$res = parse_url($link);
$result = '';
if (isset($res['scheme'])) {
$result .= $res['scheme'].'://';
}
if (isset($res['host'])) {
$result .= $res['host'];
}
if (isset($res['path'])) {
$result .= $res['path'];
}
if (isset($res['query'])) {
parse_str($res['query'], $res['query']);
} else {
$res['query'] = [];
}
$res['query']['utm'] = 'some';
$res['query']['medium'] = 'stuff';
if (count($res['query']) > 0) {
$result .= '?'.http_build_query($res['query']);
}
if (isset($hash)) {
$result .= '#'.$hash;
}
return $result;
},
$html
);
As you can see, the code is longer but simpler
Edit
I made some change, searching for every href="xxx" inside the text. If the link is not from add-link.com the script will skip it, otherwise he will try to print it in the best way possible
$html = 'blabla a
a
a
a
a
a
a
a
a
a
a
';
$url_modifier_domain = preg_quote('add-link.com');
$html_text = preg_replace_callback(
'/href="([^"]+)"/i',
function ($matches) {
$link = $matches[1];
// ignoring outer links
if(strpos($link,'add-link.com') === false) return 'href="'.$link.'"';
if (strpos($link, '#') !== false) {
list($link, $hash) = explode('#', $link);
}
$res = parse_url($link);
$result = '';
if (isset($res['scheme'])) {
$result .= $res['scheme'].'://';
} else if(isset($res['host'])) {
$result .= '//';
}
if (isset($res['host'])) {
$result .= $res['host'];
}
if (isset($res['path'])) {
$result .= $res['path'];
} else {
$result .= '/';
}
if (isset($res['query'])) {
parse_str($res['query'], $res['query']);
} else {
$res['query'] = [];
}
$res['query']['utm'] = 'some';
$res['query']['medium'] = 'stuff';
if (count($res['query']) > 0) {
$result .= '?'.http_build_query($res['query']);
}
if (isset($hash)) {
$result .= '#'.$hash;
}
return 'href="'.$result.'"';
},
$html
);
var_dump($html_text);
I try to pre-sort and slice a big XML file for later processing via xml_parser
function CreateXMLParser($CHARSET, $bareXML = false) {
$CURRXML = xml_parser_create($CHARSET);
xml_parser_set_option( $CURRXML, XML_OPTION_CASE_FOLDING, false);
xml_parser_set_option( $CURRXML, XML_OPTION_TARGET_ENCODING, $CHARSET);
xml_set_element_handler($CURRXML, 'startElement', 'endElement');
xml_set_character_data_handler($CURRXML, 'dataHandler');
xml_set_default_handler($CURRXML, 'defaultHandler');
if ($bareXML) {
xml_parse($CURRXML, '<?xml version="1.0"?>', 0);
}
return $CURRXML;
}
function ChunkXMLBigFile($file, $tag = 'item', $howmany = 1000) {
global $CHUNKON, $CHUNKS, $ITEMLIMIT;
$CHUNKON = $tag;
$ITEMLIMIT = $howmany;
$xml = CreateXMLParser('UTF-8', false);
$fp = fopen($file, "r");
$CHUNKS = 0;
while(!feof($fp)) {
$chunk = fgets($fp, 10240);
xml_parse($xml, $chunk, feof($fp));
}
xml_parser_free($xml);
processChunk();
}
function processChunk() {
global $CHUNKS, $PAYLOAD, $ITEMCOUNT;
if ('' == $PAYLOAD) {
return;
}
$xp = fopen($file = "xmlTemp/slices/slice_".$CHUNKS.".xml", "w");
fwrite($xp, '<?xml version="1.0" ?>'."\n");
fwrite($xp, "<producten>");
fwrite($xp, $PAYLOAD);
fwrite($xp, "</producten>");
fclose($xp);
print "Written ".$file."<br>";
$CHUNKS++;
$PAYLOAD = '';
$ITEMCOUNT = 0;
}
function startElement($xml, $tag, $attrs = array()) {
global $PAYLOAD, $CHUNKS, $ITEMCOUNT, $CHUNKON;
if (!($CHUNKS||$ITEMCOUNT)) {
if ($CHUNKON == strtolower($tag)) {
$PAYLOAD = '';
}
} else {
$PAYLOAD .= "<".$tag;
}
foreach($attrs as $k => $v) {
$PAYLOAD .= " $k=".'"'.addslashes($v).'"';
}
$PAYLOAD .= '>';
}
function endElement($xml, $tag) {
global $CHUNKON, $ITEMCOUNT, $ITEMLIMIT;
dataHandler(null, "<$tag>");
if ($CHUNKON == strtolower($tag)) {
if (++$ITEMCOUNT >= $ITEMLIMIT) {
processChunk();
}
}
}
function dataHandler($xml, $data) {
global $PAYLOAD;
$PAYLOAD .= $data;
}
but how can I access the node-name??
.. I have to sort some items (with n nodes) out, before the slice-file is saved. the the XML is parsed line after line, right? so I have to save the nodes from a whole item temporarely and decide if the item is gonna be written to the file.. is there a way to do this?
Your code is effectively reading the entire source file every time you call the ChunkXMLBigFile function.
After your while loop you have all the elements, which you can then manipulate any way you like.
See the following questions about how to approach this:
How to sort a xml file using DOM
Sort XML nodes with PHP
If you parse the chunks after that in batches of $howmany you are where you want to be.
Tip: there are many examples online where this functionality is presented in an Object Orient Programming (OOP) approach where all the functions are inside a class. This would also eliminate the need of global variables which can cause some (read: a lot) of frustrations and confusion.
Im using this code for create a xml file which is listing files' url and descriptions in directory. but i need to add in this xml also number of file. so i want to give to files a number (or ID), like 1 for file 2....n , like counter for every row how i can do this ?
thank you
<?php
$myfeed = new RSSFeed();
// Open the current directory (or specify it)
$dir = opendir ("./");
while (false !== ($file = readdir($dir))) {
if (strpos($file, '.jpg',1)||strpos($file, '.gif',1) ) {
$myfeed->SetItem("http://host.com/images/$file", "$file", "");
}
}
// Output the XML File
$fp = fopen('rss.xml', 'w');
fwrite($fp, $myfeed->output());
fclose($fp);
echo $myfeed->output(); //lets see that
class RSSFeed {
// VARIABLES
// channel vars
var $channel_url;
var $channel_title;
// items
var $items = array();
var $nritems;
// FUNCTIONS
// constructor
function RSSFeed() {
$this->nritems=0;
$this->channel_url='';
$this->channel_title='';
}
// set channel vars
function SetChannel($url, $title, $description, $lang, $copyright, $creator, $subject) {
$this->channel_url=$url;
$this->channel_title=$title;
}
// set item
function SetItem($url, $title, $description) {
$this->items[$this->nritems]['url']=$url;
$this->items[$this->nritems]['title']=$title;
$this->nritems++;
}
// output feed
function Output() {
$output = '<?xml version="1.0" encoding="UTF-8"?>'."\n";
$output .= '<playlist version="0" xmlns = "http://xspf.org/ns/0/">'."\n";
$output .= '<trackList>'."\n";
for($k=0; $k<$this->nritems; $k++) {
$output .= '<track>'."\n";
$output .= '<location>'.$this->items[$k]['url'].'</location>'."\n";
$output .= '<image></image>'."\n";
$output .= '<annotation>'.$this->items[$k]['title'].'</annotation>'."\n";
$output .= '</track>'."\n";
};
$output .= '</trackList>'."\n";
$output .= '</playlist>'."\n";
return $output;
}
};
?>
First up, I don't think creating XML with string-functions is a good idea, rather use a parser like simplexmlor DOM.
Assigning an id to each entry, you could take your $k in function Output():
for($k=0; $k<$this->nritems; $k++) {
$output .= '<track>'."\n";
$output .= "<id>$k</id>\n";
// (...)
$output .= "</track>\n";
}
or add id as attribute to the <track>-node:
$output .= "<track id=\"$k\">\n";
I have an a string declared at the top of my PHP script:
$dirname = "./rootfs/home/".$user."/";
After running the code, that string should be replace so it looks like this:
$dirname = "./rootfs/home/".$user."/testdir/";
Is there any way to replace the content? This is a dumb question for sure, but didn't found any way to do it, thanks! :D
Code I'm using:
Main PHP:
<?php
//Variables
$rootfs = "rootfs/";
$user = "www";
$dirname = "./rootfs/home/".$user."/";
//Variables
//Commands on rootfs/bin/
include($rootfs."/bin/ls.php");
include($rootfs."/bin/about.php");
include($rootfs."/bin/echo.php");
include($rootfs."/bin/uname.php");
include($rootfs."/bin/apt-get.php");
include($rootfs."/bin/whoami.php");
include($rootfs."/bin/cd.php");
//Commands on rootfs/bin/
$command=$_POST['command'];
$commandexp = explode(" ", $command);
switch ($commandexp[0]) {
case "cd":
//$dirname = "./rootfs/home/".$user."/";
//$prompt = cd($dirname, $commandexp[1]);
$dirname .= cd($dirname, $commandexp[1]);
echo $dirname;
break;
case "ls":
switch ($commandexp[1]) {
case "-la":
//$dirname = "./rootfs/home/".$user."/";
$files = ls($dirname);
foreach($files as $value){
$prompt .= substr(sprintf('%o', fileperms($dirname.$value)), -4)." ".$user." ".$value."<br>";
}
break;
case "--help":
$prompt = "Usage: ls [-la]";
break;
default:
echo $dirname." ";
$files = ls($dirname);
foreach($files as $value){
$prompt .= $value." ";
}
break;
}
break;
default:
$prompt = "command not found";
}
echo $prompt;
?>
The cd.php
<?php
function cd($actualdir, $dir) {
//echo $actualdir.$dir."<br>";
if(file_exists($actualdir.$dir)) {
echo $dir;
return $dir;
} else {
return "no";
}
}
?>
The ls.php
<?php
function ls ($directory) {
// create an array to hold directory list
$results = array();
// create a handler for the directory
$handler = opendir($directory);
echo $handler;
// open directory and walk through the filenames
while ($file = readdir($handler)) {
// if file isn't this directory or its parent, add it to the results
if ($file != "." && $file != "..") {
$results[] = $file;
}
}
// tidy up: close the handler
closedir($handler);
// done!
return $results;
}
?>
To add a string just do that:
$dirname .= "/testdir/";
To concatenate one string to the end of another string: $dirname .= 'testdir/'
To reassign a totally new string to the variable: $dirname = 'This is the new string'
See String Operators
Is this what you want:
$dirname .= "testdir/";
Finally used a session variable for storing the actual dir
Hello everyone Masters Of Web Delevopment :)
I have a piece of PHP script that fetches last 10 played songs from my winamp. This script is inside file (lets call it "lastplayed.php") which is included in my site with php include function inside a "div".
My site is on UTF-8 encoding. The problem is that some songs titles are in Windows-1251 encoding. And in my site they displays like "������"...
Is there any known way to tell to this div with included "lastplayed.php" in it, to be with windows-1251 encoding?
Or any other suggestions?
P.S: The file with fetching script a.k.a. "lastplayed.php", is converted to UTF-8. But if it is ANCII it's the same result. I try to put and meta tag with windows-1251 between head tag but nothing happens again.
P.P.S: Script that fetches the Winamp's data (lastplayed.php):
<?php
/******
* You may use and/or modify this script as long as you:
* 1. Keep my name & webpage mentioned
* 2. Don't use it for commercial purposes
*
* If you want to use this script without complying to the rules above, please contact me first at: marty#excudo.net
*
* Author: Martijn Korse
* Website: http://devshed.excudo.net
*
* Date: 08-05-2006
***/
/**
* version 2.0
*/
class Radio
{
var $fields = array();
var $fieldsDefaults = array("Server Status", "Stream Status", "Listener Peak", "Average Listen Time", "Stream Title", "Content Type", "Stream Genre", "Stream URL", "Current Song");
var $very_first_str;
var $domain, $port, $path;
var $errno, $errstr;
var $trackLists = array();
var $isShoutcast;
var $nonShoutcastData = array(
"Server Status" => "n/a",
"Stream Status" => "n/a",
"Listener Peak" => "n/a",
"Average Listen Time" => "n/a",
"Stream Title" => "n/a",
"Content Type" => "n/a",
"Stream Genre" => "n/a",
"Stream URL" => "n/a",
"Stream AIM" => "n/a",
"Stream IRC" => "n/a",
"Current Song" => "n/a"
);
var $altServer = False;
function Radio($url)
{
$parsed_url = parse_url($url);
$this->domain = isset($parsed_url['host']) ? $parsed_url['host'] : "";
$this->port = !isset($parsed_url['port']) || empty($parsed_url['port']) ? "80" : $parsed_url['port'];
$this->path = empty($parsed_url['path']) ? "/" : $parsed_url['path'];
if (empty($this->domain))
{
$this->domain = $this->path;
$this->path = "";
}
$this->setOffset("Current Stream Information");
$this->setFields(); // setting default fields
$this->setTableStart("<table border=0 cellpadding=2 cellspacing=2>");
$this->setTableEnd("</table>");
}
function setFields($array=False)
{
if (!$array)
$this->fields = $this->fieldsDefaults;
else
$this->fields = $array;
}
function setOffset($string)
{
$this->very_first_str = $string;
}
function setTableStart($string)
{
$this->tableStart = $string;
}
function setTableEnd($string)
{
$this->tableEnd = $string;
}
function getHTML($page=False)
{
if (!$page)
$page = $this->path;
$contents = "";
$domain = (substr($this->domain, 0, 7) == "http://") ? substr($this->domain, 7) : $this->domain;
if (#$fp = fsockopen($domain, $this->port, $this->errno, $this->errstr, 2))
{
fputs($fp, "GET ".$page." HTTP/1.1\r\n".
"User-Agent: Mozilla/4.0 (compatible; MSIE 5.5; Windows 98)\r\n".
"Accept: */*\r\n".
"Host: ".$domain."\r\n\r\n");
$c = 0;
while (!feof($fp) && $c <= 20)
{
$contents .= fgets($fp, 4096);
$c++;
}
fclose ($fp);
preg_match("/(Content-Type:)(.*)/i", $contents, $matches);
if (count($matches) > 0)
{
$contentType = trim($matches[2]);
if ($contentType == "text/html")
{
$this->isShoutcast = True;
return $contents;
}
else
{
$this->isShoutcast = False;
$htmlContent = substr($contents, 0, strpos($contents, "\r\n\r\n"));
$dataStr = str_replace("\r", "\n", str_replace("\r\n", "\n", $contents));
$lines = explode("\n", $dataStr);
foreach ($lines AS $line)
{
if ($dp = strpos($line, ":"))
{
$key = substr($line, 0, $dp);
$value = trim(substr($line, ($dp+1)));
if (preg_match("/genre/i", $key))
$this->nonShoutcastData['Stream Genre'] = $value;
if (preg_match("/name/i", $key))
$this->nonShoutcastData['Stream Title'] = $value;
if (preg_match("/url/i", $key))
$this->nonShoutcastData['Stream URL'] = $value;
if (preg_match("/content-type/i", $key))
$this->nonShoutcastData['Content Type'] = $value;
if (preg_match("/icy-br/i", $key))
$this->nonShoutcastData['Stream Status'] = "Stream is up at ".$value."kbps";
if (preg_match("/icy-notice2/i", $key))
{
$this->nonShoutcastData['Server Status'] = "This is <span style=\"color: red;\">not</span> a Shoutcast server!";
if (preg_match("/ultravox/i", $value))
$this->nonShoutcastData['Server Status'] .= " But an Ultravox Server";
$this->altServer = $value;
}
}
}
return nl2br($htmlContent);
}
}
else
return $contents;
}
else
{
return False;
}
}
function getServerInfo($display_array=null, $very_first_str=null)
{
if (!isset($display_array))
$display_array = $this->fields;
if (!isset($very_first_str))
$very_first_str = $this->very_first_str;
if ($html = $this->getHTML())
{
// parsing the contents
$data = array();
foreach ($display_array AS $key => $item)
{
if ($this->isShoutcast)
{
$very_first_pos = stripos($html, $very_first_str);
$first_pos = stripos($html, $item, $very_first_pos);
$line_start = strpos($html, "<td>", $first_pos);
$line_end = strpos($html, "</td>", $line_start) + 4;
$difference = $line_end - $line_start;
$line = substr($html, $line_start, $difference);
$data[$key] = strip_tags($line);
}
else
{
$data[$key] = $this->nonShoutcastData[$item];
}
}
return $data;
}
else
{
return $this->errstr." (".$this->errno.")";
}
}
function createHistoryArray($page)
{
if (!in_array($page, $this->trackLists))
{
$this->trackLists[] = $page;
if ($html = $this->getHTML($page))
{
$fromPos = stripos($html, $this->tableStart);
$toPos = stripos($html, $this->tableEnd, $fromPos);
$tableData = substr($html, $fromPos, ($toPos-$fromPos));
$lines = explode("</tr><tr>", $tableData);
$tracks = array();
$c = 0;
foreach ($lines AS $line)
{
$info = explode ("</td><td>", $line);
$time = trim(strip_tags($info[0]));
if (substr($time, 0, 9) != "Copyright" && !preg_match("/Tag Loomis, Tom Pepper and Justin Frankel/i", $info[1]))
{
$this->tracks[$c]['time'] = $time;
$this->tracks[$c++]['track'] = trim(strip_tags($info[1]));
}
}
if (count($this->tracks) > 0)
{
unset($this->tracks[0]);
if (isset($this->tracks[1]))
$this->tracks[1]['track'] = str_replace("Current Song", "", $this->tracks[1]['track']);
}
}
else
{
$this->tracks[0] = array("time"=>$this->errno, "track"=>$this->errstr);
}
}
}
function getHistoryArray($page="/played.html")
{
if (!in_array($page, $this->trackLists))
$this->createHistoryArray($page);
return $this->tracks;
}
function getHistoryTable($page="/played.html", $trackColText=False, $class=False)
{
$title_utf8 = mb_convert_encoding($trackArr ,"utf-8" ,"auto");
if (!in_array($page, $this->trackLists))
$this->createHistoryArray($page);
if ($trackColText)
$output .= "
<div class='lastplayed_top'></div>
<div".($class ? " class=\"".$class."\"" : "").">";
foreach ($this->tracks AS $title_utf8)
$output .= "<div style='padding:2px 0;'>".$title_utf8['track']."</div>";
$output .= "</div><div class='lastplayed_bottom'></div>
<div class='lastplayed_title'>".$trackColText."</div>
\n";
return $output;
}
}
// this is needed for those with a php version < 5
// the function is copied from the user comments # php.net (http://nl3.php.net/stripos)
if (!function_exists("stripos"))
{
function stripos($haystack, $needle, $offset=0)
{
return strpos(strtoupper($haystack), strtoupper($needle), $offset);
}
}
?>
And the calling script outside the lastplayed.php:
include "lastplayed.php";
$radio = new Radio($ip.":".$port);
echo $radio->getHistoryTable("/played.html", "<b>Last played:</b>", "lastplayed_content");
If all of your source data is in windows-1251, you can use something like:
$title_utf8=mb_convert_encoding($title,"utf-8","Windows-1251")
and put that converted data in your HTML stream.
Since I'm only looking at docs, I'm not 100% sure that the source encoding alias is correct; you may want to try CP1251 if Windows-1251 doesn't work.
If your source data isn't reliably in 1251, you'll have to come up with a heuristic to guess, and use the same conversion method. mb_detect_encoding may help you.
You cannot change the encoding of just part of an HTML document, but you can certainly convert everything to UTF-8 easily enough.
The newer ID3 implementations have an encoding marker in their text frames:
$00 ISO-8859-1 (ASCII)
$01 – UCS-2 in ID3v2.2 and ID3v2.3, UTF-16 encoded Unicode with BOM.
$02 – UTF-16BE encoded Unicode without BOM in ID3v2.4 only.
$03 – UTF-8 encoded Unicode in ID3v2.4 only.
Is it possible that your content is in UTF16?
Based on the code you've posted, it's not clear how $trackArr is defined, as it's not referenced elsewhere. It looks like you have several problems.
$title_utf8 = mb_convert_encoding($trackArr ,"utf-8" ,"auto")
"auto" expands to a list of encodings that do not include Windows-1251, so I'm not sure why you've used it. You really should use "Windows-1251". I have tried using "Windows-1251,utf-16" on a mac with PHP installed, but autodetect fails to find a suitable encoding against a relatively short string, so it looks like you're going to have to be the one to guess.
But that code doesn't look like it has any reason to exist anyway, as you overwrite the values with your iteration:
foreach ($this->tracks AS $title_utf8)
$output .= "<div style='padding:2px 0;'>".$title_utf8['track'].\"</div>";
In each iteration, the variable $title_utf8 is assigned to the current track. What you probably want is something more like:
foreach ($this->tracks AS $current_track)
$output .= "<div style='padding:2px 0;'>". mb_convert_encoding($current_track ,"utf-8" ,"Windows-1251");
mb_convert_encoding takes a string as the first argument, not an array or object, so you need to apply this encoding on each string that is not utf-8.
Just to let you know that the latest version supports character encoding/decoding :-)