The below code successfully saves the child div but also saves some numbers in the file at the end. I think its the bytes of data present, how do i get rid of the numbers it saves?
$file = '../userfolders/'.$email.'/'.$ongrassdb.'/'.$pagenameselected.'.php';
$doc = new DOMDocument();
$doc->load($file);
$ele = $doc->createElement('div', $textcon);
$ele ->setAttribute('id', $divname);
$ele ->setAttribute('style', 'background: '.$divbgcolor.'; color :'.$divfontcolor.' ;display : table-cell;');
$element = $doc->getElementsByTagName('div')->item(0);
$element->appendChild($ele);
$doc->appendChild($element);
$myfile = fopen($file, "a+") or die('Unable to open file!');
$html = $doc->save($file);
fwrite($myfile,$html);
fclose($myfile);
I don't want to use saveHTML nor saveHTMLFile because it creates multiple instances of the divs and adds html tags to it.
$doc->load($file);
...
$myfile = fopen($file, "a+") or die('Unable to open file!');
$html = $doc->save($file);
fwrite($myfile,$html);
fclose($myfile);
The $doc->save() method saves the DOM tree to the file, and returns the number of bytes it wrote to the file. This number is stored in $html and is then append to the same file by fwrite().
Just remove the fopen(), fwrite() and fclose() calls.
I removed the last two lines and it solved the issue
fwrite($myfile,$html);
fclose($myfile);
Related
Goal
What I'm aiming to achieve is to create a small web app where the user can edit certain elements such as img src, href, etc. Then save it to a file.
I've created the basic code which allows the user to edit however I'm struggling to take the amended code and save it to a .html file.
Progress
<?php
function getHTMLByID($id, $html) {
$dom = new DOMDocument;
libxml_use_internal_errors(true);
$dom->loadHTML($html);
$node = $dom->getElementById($id);
if ($node) {
return $dom->saveXML($node);
}
return FALSE;
}
$html = file_get_contents('http://www.mysql.com/');
$codeString = getHTMLByID('l1-nav-container', $html);
echo $codeString;
$myfile = fopen("newfile.html", "w") or die("Unable to open file!");
fwrite($myfile, $codeString);
fclose($myfile);
?>
I've created some basic code which saves a string to a file which is being received from another website however, I can't seem to work out how to get the code from the page.
I'm parsing an html file, and getting contents of a pre tag then saving it to a text file.
however when i open the text file in sublime, or other text editors the formmating is gone,
My question: how can i save the text in its original state inside the txt file.
the contents of the pre are below this:
x4 x4
|---------------------|-|-------------------|--------------------|
|---------------------|-|-------------------|--------------------|
|----------2-0-0------|-|-------------------|--------------------|
|----------------1-0-0|-|-------------------|--------------------|
|3-0-1-3-0------------|0|1-3-1-3-1-3-1-0----|1-3-1-3-1-3-1-0---0-|
x4 x4
|------------------------|-------------|-------------------|
|------------------------|-------------|-------------------|
|------------------------|-------------|-------------------|
|------------------------|-------------|0--0033------------|
|1-3-1-3-1-3-1-0--0000--0|1-3-1-3-1-3-1|--------333~-335-0-|
x4 x4
|------------------------|---------------------|-|-------------|
|------------------------|---------------------|-|-------------|
|------------------------|----------2-0-0------|-|-------------|
|------------------------|----------------1-0-0|-|-------------|
|0--0000--0-1-3-1-3-1-3-1|3-0-1-3-0------------|0|1-3-1-3-1-3-1|
my code:
<?php
// example of how to use basic selector to retrieve HTML contents
include('simple_html_dom.php');
// get DOM from URL or file
$html = file_get_html('http://metaltabs.com/tab/10464/index.html');
foreach($html->find('title') as $e)
echo $e->innertext . '<br>';
$my_file = fopen("textfile.txt", "w") or die("Unable to open file!");
foreach($html->find('pre') as $e)
echo nl2br($e->innertext) . '<br>';
$txt = $e->innertext;
fwrite($my_file, $txt);
fclose($my_file);
?>
The problems with your parsing results are:
Line breaks are not preserved;
HTML entities are preserved.
To resolve line break issue you have to use ->load() instead of file_get_html:
$html = new simple_html_dom();
$data = file_get_contents( 'http://metaltabs.com/tab/10464/index.html' );
$html->load( $data , True, False );
/* └─┬┘ └─┬─┘
Optional parameter Optional parameter
lowercase Strip \r\n
*/
To resolve entities issue you can use php function ``:
$txt = html_entity_decode( $e->innertext );
The result is something like this:
Tuning E A D G B E
|------------------------------------------------------------|
|------------------------------------------------------------|
|------------------------------------------------------------|
|------------------------------------------------------------|
|-------<7-8>----------<10-11>---------<7-8>---7--10--8--11--|x9
|-0000-----------0000------------0000----------0-------------|
I tried this code and opening with sublime text, the text file preserve the same formatting as in your website:
$html = file_get_contents("http://metaltabs.com/tab/4086/index.html");
$dom = new domDocument('1.0', 'utf-8');
// load the html into the object
$dom->loadHTML($html);
//preserve white space
$dom->preserveWhiteSpace = true;
$pre= $dom->getElementsByTagName('pre');
$file = fopen('text.txt', 'w');
fwrite($file, $pre->item(0)->nodeValue);
fclose($file);
This is assuming that you are sure that there is only one pre tag in your page, otherwise you have to loop through the $pre variable
Bassicly what I want to do is using PHP open a xml file and edit it using php now this I can do using fopen() function.
Yet my issue it that i want to append text to the middle of the document. So lets say the xml file has 10 lines and I want to append something before the last line (10) so now it will be 11 lines. Is this possible. Thanks
Depending on how large that file is, you might do:
$lines = array();
$fp = fopen('file.xml','r');
while (!feof($fp))
$lines[] = trim(fgets($fp));
fclose($fp);
array_splice($lines, 9, 0, array('newline1','newline2',...));
$new_content = implode("\n", $lines);
Still, you'll need to revalidate XML-syntax afterwards...
If you want to be able to modify a file from the middle, use the c+ open mode:
$fp = fopen('test.txt', 'c+');
for ($i=0;$i<5;$i++) {
fgets($fp);
}
fwrite($fp, "foo\n");
fclose($fp);
The above will write "foo" on the fifth line, without having to read the file entirely.
However, if you are modifying a XML document, it's probably better to use a DOM parser:
$dom = new DOMDocument;
$dom->load('myfile.xml');
$linenum = 5;
$newNode = $dom->createElement('hello', 'world');
$element = $dom->firstChild->firstChild; // skips the root node
while ($element) {
if ($element->getLineNo() == $linenum) {
$element->parentNode->insertBefore($newNode, $element);
break;
}
$element = $element->nextSibling;
}
echo $dom->saveXML();
Of course, the above code depends on the actual XML document structure. But, the $element->getLineNo() is the key here.
I am trying to format visually how my XML file looks when it is output. Right now if you go here and view the source you will see what the file looks like.
The PHP I have that creates the file is: (Note, $links_array is an array of urls)
header('Content-Type: text/xml');
$sitemap = new DOMDocument;
// create root element
$root = $sitemap->createElement("urlset");
$sitemap->appendChild($root);
$root_attr = $sitemap->createAttribute('xmlns');
$root->appendChild($root_attr);
$root_attr_text = $sitemap->createTextNode('http://www.sitemaps.org/schemas/sitemap/0.9');
$root_attr->appendChild($root_attr_text);
foreach($links_array as $http_url){
// create child element
$url = $sitemap->createElement("url");
$root->appendChild($url);
$loc = $sitemap->createElement("loc");
$lastmod = $sitemap->createElement("lastmod");
$changefreq = $sitemap->createElement("changefreq");
$url->appendChild($loc);
$url_text = $sitemap->createTextNode($http_url);
$loc->appendChild($url_text);
$url->appendChild($lastmod);
$lastmod_text = $sitemap->createTextNode(date("Y-m-d"));
$lastmod->appendChild($lastmod_text);
$url->appendChild($changefreq);
$changefreq_text = $sitemap->createTextNode("weekly");
$changefreq->appendChild($changefreq_text);
}
$file = "sitemap.xml";
$fh = fopen($file, 'w') or die("Can't open the sitemap file.");
fwrite($fh, $sitemap->saveXML());
fclose($fh);
}
As you can tell by looking at the source, the file isn't as readable as I would like it to be. Is there any way for me to format the nodes?
Thanks,
Levi
Checkout the formatOutput setting in DOMDocument.
$sitemap->formatOutput = true
not just PHP, there is a stylesheet for XML: XSLT, which can format XML into sth looks good.
I have:
<?php
$file=fopen(date("Y-m-d").".txt","r+") or exit("Unable to open file!");
if ($_POST["lastname"] <> "")
{
fwrite($file,$_POST["lastname"]."\n");
}
fclose($file);
?>
but it overwrites the beginning of the file. How do I make it insert?
I'm not entirely sure of your question - do you want to write data and not have it over-write the beginning of an existing file, or write new data to the start of an existing file, keeping the existing content after it?
To insert text without over-writing the beginning of the file, you'll have to open it for appending (a+ rather than r+)
$file=fopen(date("Y-m-d").".txt","a+") or exit("Unable to open file!");
if ($_POST["lastname"] <> "")
{
fwrite($file,$_POST["lastname"]."\n");
}
fclose($file);
If you're trying to write to the start of the file, you'll have to read in the file contents (see file_get_contents) first, then write your new string followed by file contents to the output file.
$old_content = file_get_contents($file);
fwrite($file, $new_content."\n".$old_content);
The above approach will work with small files, but you may run into memory limits trying to read a large file in using file_get_conents. In this case, consider using rewind($file), which sets the file position indicator for handle to the beginning of the file stream.
Note when using rewind(), not to open the file with the a (or a+) options, as:
If you have opened the file in append ("a" or "a+") mode, any data you write to the file will always be appended, regardless of the file position.
A working example for inserting in the middle of a file stream without overwriting, and without having to load the whole thing into a variable/memory:
function finsert($handle, $string, $bufferSize = 16384) {
$insertionPoint = ftell($handle);
// Create a temp file to stream into
$tempPath = tempnam(sys_get_temp_dir(), "file-chainer");
$lastPartHandle = fopen($tempPath, "w+");
// Read in everything from the insertion point and forward
while (!feof($handle)) {
fwrite($lastPartHandle, fread($handle, $bufferSize), $bufferSize);
}
// Rewind to the insertion point
fseek($handle, $insertionPoint);
// Rewind the temporary stream
rewind($lastPartHandle);
// Write back everything starting with the string to insert
fwrite($handle, $string);
while (!feof($lastPartHandle)) {
fwrite($handle, fread($lastPartHandle, $bufferSize), $bufferSize);
}
// Close the last part handle and delete it
fclose($lastPartHandle);
unlink($tempPath);
// Re-set pointer
fseek($handle, $insertionPoint + strlen($string));
}
$handle = fopen("file.txt", "w+");
fwrite($handle, "foobar");
rewind($handle);
finsert($handle, "baz");
// File stream is now: bazfoobar
Composer lib for it can be found here
You get the same opening the file for appending
<?php
$file=fopen(date("Y-m-d").".txt","a+") or exit("Unable to open file!");
if ($_POST["lastname"] <> "")
{
fwrite($file,$_POST["lastname"]."\n");
}
fclose($file);
?>
If you want to put your text at the beginning of the file, you'd have to read the file contents first like:
<?php
$file=fopen(date("Y-m-d").".txt","r+") or exit("Unable to open file!");
if ($_POST["lastname"] <> "")
{
$existingText = file_get_contents($file);
fwrite($file, $existingText . $_POST["lastname"]."\n");
}
fclose($file);
?>