Note: I'm sorry if the title was a little unclear couldn't think of another way to put it.
I am making a PHP posting system for a blog like website. I have a file called posts.txt which has information that points to other text files. These other text files have the physical post content in them. I know this is not the best way to do it but for now this is what I'm doing.
A sample of the posts.txt:
posts/topDownShooter.txt
posts/leapMotionSandbox.txt
end
The first two lines point to other text files that contain post content. The last line "end" lets the program know that all the post "pointers" are done
Here is a sample of a post like topDownShooter.txt
programming
Top Down Shooter
The actual post content goes here
end
The first line is a tag for organization. The second line is the title of the post. And the third is the actual content. The last line serves the same purpose.
Here is my PHP code:
I use "<--" for comments
<?php
$posts = "posts/posts.txt"; <--Pointer to the location of the posts.txt
$postsLines = file($posts);
$fetchingPost = TRUE; <--For while loop
$postNumber = 0;
$postPointer; <--In the example of posts.txt this would be the second or third line
$postTag;
$postTitle;
$postContent;
$endCondition = "end";
while ($fetchingPost == TRUE) {
$endOfFile = strcmp($postsLines[$postNumber], $endCondition);
if ($endOfFile == 0) {
$fetchingPost = FALSE;
}
if ($endOfFile <> 0) {
$postPointer[$postNumber] = $postsLines[$postNumber];
$postTag[$postNumber] = file($postPointer[$postNumber]); <--The problem, see below
$postNumber = $postNumber + 1;
}
}
?>
The Problem: It will not let me use a line that I take out of posts.txt as a "pointer" for accessing topDownShooter.txt or anything like that. I thought that the value I was pulling out of posts.txt was a string but it is not. Is there anyway that I can convert this to a string or make it work?
EDIT:
in short:
is there anyway to take something from $postsLines = file("somerandomtxtfile.txt); and make %postsLines[0] a string?
I'm not sure if I understand your question, but I'd try replacing the line by this
$postTag[$postNumber] = file_get_contents($postPointer[$postNumber]);
Answering the question in your edit, you can do that like this:
$postLines = explode(PHP_EOL, file_get_contents("somerandomtxtfile.txt"));
Related
I have a php script getting all folders in a posts folder and making them into a list.
I have a $postinfo_str variable assigned to a json file for each folder which I am using to store post date and category/tag info etc in.
I also have a $pagetitle variable assigned to a title.php include file for each folder. So say I am on a "June 2018" archive page, the text in that file will be "June 2018". If I am on say a "Tutorials" category page, that will be the text in the title.php.
In the json file, I have:
{
"Arraysortdate": "YYYYMMDD",
"Month": "Month YYYY",
"Category": ["cat1", "cat2", "etc"]
}
I am ordering the array newest to oldest using krsort with Arraysortdate as key.
How do I filter the array using $pagetitle as input, finding if there is a match in $postinfo_str, and if there isn't, remove that folder from the array?
All I can seem to find regarding array sorting is where the info in the $pageinfo_str is basically the array and so by that, the $title is the input and the output is the matching text from the $postinfo_str, whereas I want the output to be the folders that only have the matching text in the $postinfo_str to what the input ($pagetitle) is.
Here is my code I have.. Keep in mind this is flat file, I do not want a database to achieve this. See comments if you want an explaination.
<?php
$BASE_PATH = '/path/to/public_html';
// initial array containing the dirs
$dirs = glob($BASE_PATH.'/testblog/*/posts/*', GLOB_ONLYDIR);
// new array with date as key
$dirinfo_arr = [];
foreach ($dirs as $cdir) {
// get current page title from file
$pagetitle = file_get_contents("includes/title.php");
// get date & post info from file
$dirinfo_str = file_get_contents("$cdir/includes/post-info.json");
$dirinfo = json_decode($dirinfo_str, TRUE);
// add current directory to the info array
$dirinfo['dir'] = $cdir;
// add current dir to new array where date is the key
$dirinfo_arr[$dirinfo['Arraysortdate']] = $dirinfo;
}
// now we sort the new array
krsort($dirinfo_arr);
foreach($dirinfo_arr as $key=>$dir) {
$dirpath = $dir['dir'];
$dirpath = str_replace('/path/to/public_html/', '', $dirpath);
?>
<!--HTML HERE SUCH AS--!>
TEXT <br>
<?php
};
?>
I have difficulties following your problem description. Your code example is slightly confusing. It appears to load the same global includes/title.php for each directory. Meaning, the value of $pagetitle should be the same every iteration. If this is intended, you should probably move that line right outside the loop. If the file contains actual php code, you should probably use
$pagetitle = include 'includes/title.php';
or something similar. If it doesn't, you should probably name it title.txt. If it is not one global file, you should probably add the path to the file_get_contents/include as well. (However, why wouldn't you just add the title in the json struct?)
I'm under the assumption that this happened by accident when trying to provide a minimal code example (?) ... In any case, my answer won't be the perfect answer, but it hopefully can be adapted once understood ;o)
If you only want elements in your array, that fulfill certain properties, you have essentially two choices:
don't put those element in (mostly your code)
foreach ($dirs as $cdir) {
// get current page title from file
$pagetitle = file_get_contents("includes/title.php");
// get date & post info from file
$dirinfo_str = file_get_contents("$cdir/includes/post-info.json");
$dirinfo = json_decode($dirinfo_str, TRUE);
// add current directory to the info array
$dirinfo['dir'] = $cdir;
// add current dir to new array where date is the key
// ------------ NEW --------------
$filtercat = 'cat1';
if(!in_array($filtercat, $dirinfo['Category'])) {
continue;
}
// -------------------------------
$dirinfo_arr[$dirinfo['Arraysortdate']] = $dirinfo;
array_filter the array afterwards, by providing a anonymous function
// ----- before cycling through $dirinfo_arr for output
$filtercat = 'cat1';
$filterfunc = function($dirinfo) use ($filtercat) {
return in_array($filtercat, $dirinfo['Category']));
}
$dirinfo_arr = array_filter($dirinfo_arr, $filterfunc);
you should read up about anonymous functions and how you provide local vars to them, to ease the pain. maybe your use case is bettersuited for array_reduce, which is similar, except you can determine the output of your "filter".
$new = array_filter($array, $func), is just a fancy way of writing:
$new = [];
foreach($array as $key => $value) {
if($func($value)) {
$new[$key] = $value;
}
}
update 1
in my code samples, you could replace in_array($filtercat, $dirinfo['Category']) with in_array($pagetitle, $dirinfo) - if you want to match on anything that's in the json-struct (base level) - or with ($pagetitle == $dirinfo['Month']) if you just want to match the month.
update 2
I understand, that you're probably just starting with php or even programming, so the concept of some "huge database" may be frightening. But tbh, the filesystem is - from a certain point of view - a database as well. However, it usually is quite slow in comparison, it also doesn't provide many features.
In the long run, I would strongly suggest using a database. If you don't like the idea of putting your data in "some database server", use sqlite. However, there is a learning curve involved, if you never had to deal with databases before. In the long run it will be time worth spending, because it simplifys so many things.
So i have this code, $value2 is an array of values that I edit.
I have .txt document for each of the variable in the array.. for exemple
sometext_AA.txt
sometext_BB.txt
I currently have over 50 text files, and it make a BIG BIG BIG php files because i have the following code made for each of the files for exemple sometext_AA.txt...
I would like to make one script(the following) so that one script will work for all of my $value2(I do not delete the old texts files when the value are changed so i am unable to just make script to read all different text file, it has to be done that it read the active $value2 and process them...
I am not even sure if I am on the good way but i really hope someone can help me out.
Thank you!
$value2 = array("AA","BB","CC");
foreach($value2 as $value3) {
foreach($random1_' .$value3' as $random2_' .$value3') {
$random3_' .$value3' = 'sometext_.$value3'.txt;
$random4_' .$value3' = json_encode(file_get_contents($random3_' .$value3'));
echo $random4_' .$value3';
}
}
This is a exemple of current text i have in my file, I have a very big php file, and, id like a code to make it simple
foreach($random1_AA as $random2_AA) {
$random3_AA = 'sometext_AA.txt;
$random4_AA = json_encode(file_get_contents($random3_AA));
echo $random4_AA;
}
foreach($random1_BB as $random2_BB) {
$random3_BB = 'sometext_BB.txt;
$random4_BB = json_encode(file_get_contents($random3_BB));
echo $random4_BB;
}
foreach($random1_CC as $random2_CC) {
$random3_CC = 'sometext_CC.txt;
$random4_CC = json_encode(file_get_contents($random3_CC));
echo $random4_CC;
}
foreach($random1_DD as $random2_DD) {
$random3_DD = 'sometext_DD.txt;
$random4_DD = json_encode(file_get_contents($random3_DD));
echo $random4_DD;
}
I think that this is what you are looking for, using the $var_{$var_in_var} syntax that PHP allows (so you can include a variable in a variable name).
$value2 = array("AA","BB","CC");
foreach($value2 as $value3) {
foreach($random1_{$value3} as $random2_{$value3}) {
$random3_{$value3} = 'sometext_'.$value3.'.txt';
$random4_{$value3} = json_encode(file_get_contents($random3_{$value3}));
echo $random4_{$value3};
}
}
However, I stongly advise you to consider the following points in order to make your code maintainable:
Use appropriate variable names representing the real content of each variable (you shoud never use "value1", "value2", etc. as the name tells nothing about the variable content).
Don't use variables in variable names unless absolutely necessary, which is not your case. You can use arrays, which are better suited for doing that.
In fact, I don't even know what $random1_XX and $random2_XX are supposed to be. I don't see you defining them in the code sample you posted.
Here is an example of how clear and concise you code may be if you use my advice and if all you need to read all the files and print them in JSON format (which is the only thing the program sample you posted would be doing after corrections).
$file_codes = array('AA', 'BB', 'CC');
foreach($file_codes as $file_code) {
echo json_encode(file_get_contents('sometext_'.$file_code.'.txt'));
}
Of course, if you have anything else in your program (maybe some code using the variables $random3_XX and $random4_XX?), I cannot guess what it is so I can't really offer you help to optimize this code.
I have a file like this
**buffer.php**
ob_start();
<h1>Welcome</h1>
{replace_me_with_working_php_include}
<h2>I got a problem..</h2>
ob_end_flush();
Everything inside the buffer is dynamically made with data from the database.
And inserting php into the database is not an option.
The issue is, I got my output buffer and i want to replace '{replace}' with a working php include, which includes a file that also has some html/php.
So my actual question is: How do i replace a string with working php-code in a output-buffer?
I hope you can help, have used way to much time on this.
Best regards - user2453885
EDIT - 25/11/14
I know wordpress or joomla is using some similar functions, you can write {rate} in your post, and it replaces it with a rating system(some rate-plugin). This is the secret knowledge I desire.
You can use preg_replace_callback and let the callback include the file you want to include and return the output. Or you could replace the placeholders with textual includes, save that as a file and include that file (sort of compile the thing)
For simple text you could do explode (though it's probably not the most efficient for large blocks of text):
function StringSwap($text ="", $rootdir ="", $begin = "{", $end = "}") {
// Explode beginning
$go = explode($begin,$text);
// Loop through the array
if(is_array($go)) {
foreach($go as $value) {
// Split ends if available
$value = explode($end,$value);
// If there is an end, key 0 should be the replacement
if(count($value) > 1) {
// Check if the file exists based on your root
if(is_file($rootdir . $value[0])) {
// If it is a real file, mark it and remove it
$new[]['file'] = $rootdir . $value[0];
unset($value[0]);
}
// All others set as text
$new[]['txt'] = implode($value);
}
else
// If not an array, not a file, just assign as text
$new[]['txt'] = $value;
}
}
// Loop through new array and handle each block as text or include
foreach($new as $block) {
if(isset($block['txt'])) {
echo (is_array($block['txt']))? implode(" ",$block['txt']): $block['txt']." ";
}
elseif(isset($block['file'])) {
include_once($block['file']);
}
}
}
// To use, drop your text in here as a string
// You need to set a root directory so it can map properly
StringSwap($text);
I might be misunderstanding something here, but something simple like this might work?
<?php
# Main page (retrieved from the database or wherever into a variable - output buffer example shown)
ob_start();
<h1>Welcome</h1>
{replace_me_with_working_php_include}
<h2>I got a problem..</h2>
$main = ob_get_clean();
# Replacement
ob_start();
include 'whatever.php';
$replacement = ob_get_clean();
echo str_replace('{replace_me_with_working_php_include}', $replacement, $main);
You can also use a return statement from within an include file if you wish to remove the output buffer from that task too.
Good luck!
Ty all for some lovely input.
I will try and anwser my own question as clear as I can.
problem: I first thought that I wanted to implement a php-function or include inside a buffer. This however is not what I wanted, and is not intended.
Solution: Callback function with my desired content. By using the function preg_replace_callback(), I could find the text I wanted to replace in my buffer and then replace it with whatever the callback(function) would return.
The callback then included the necessary files/.classes and used the functions with written content in it.
Tell me if you did not understand, or want to elaborate/tell more about my solution.
I was goog for hours and just cannot find an answer. Please suggest:
Having a .html file that contains only user comments in paragraphs like:
<p>12/02/2012 4:32pm Mark</p>
<p>Hi! it's a nice demo! Really thankful</p>
<hr>
<p>11/02/2012 11:03am Miron</p>
<p>How to change the font size from CFD again?</p>
<hr>
<!-- AND LOADS OF OTHER <P><P> COMMENTS DELIMITED BY <HR> ... -->
There's 1000's of comments structured like this,
I'd like to grab somehow the newest 10 (not by date, just the first 'ten' comments). And I don't know how.
I know I can use jQuery's .load('comments.html') and than remove all the elements but the first 10 comments, or even include the whole file with PHP and than do the .hide() with jQuery... but it's a good idea to load the whole file for just 10 comments?
How to split that file and get inside an <div id="latest_10_comments"></div> the first 10 comments from the comments.html file?
I know you wanted a JavaScript solution but you could do this in PHP by using the explode function.
Something like this:
$comments = explode("<hr>", file_get_contents("/comments.html"));
for($i = 0; $i < 10; $i++) {
print($comments[$i]);
}
This creates an array called $comments which is each comment in comments.html separated by a
<hr>
tag.
First, I'd suggest reconsidering your approach to this problem entirely. Why are you storing everything an in HTML file this way? You should either store it as an XML file or store it in your database if you want to dynamically load certain comments on demand.
However, to answer your question you're going to need to use an X/HTML parser like PHP's DomDocument if you want to do this in PHP. Here's a working example...
EDIT (changed to reflect the OP's desired behavior):
$dom = new DomDocument;
$dom->loadHTMLFile("comments.html");
// Get all the P tag elements in the DOM
$comments = $dom->getElementsByTagName('p');
// Get only the first 10
$amount = 10; // number of comments you want
foreach ($comments as $num => $comment_nodes) {
if ($num + 1 > $amount)
break;
echo $comment_nodes->nodeValue, PHP_EOL;
}
Solution 1. You can use a RegEx pattern to match 2 p tags followed by hr and repeat the pattern for 10 times.
Solution 2.
Idea from other answer(CHRIS), but as that has error in PHP, I am suggesting this.
$comments = explode("<hr>", file_get_contents("/comments.html"));
for($i = 0; $i < 10; $i++) {
print($comments[$i]);
}
$("<p>").each(function(index, value)
{
//Do what you want here
}
This will cycle through all your <p>. If you know the order of the elements then you can do what you want with them based on index.
I am having one hell of a time coming up with a decent way make this if statement search a file for these codes. I set up the text file to read from as such:
myfile.txt
r)
0Y7
1a6
q.
#g
#(
#a
!P
T[
V}
0,
Here is a brief of what I got going.
$subject = file_get_contents(fvManager_Path . 'myfile.txt');
if ( preg_match('/^[a-zA-Z0-9,]+$/',$result['fmbushels_itemCode'], $subject) ) {
Basically I am trying to search the text file line by line to see if the whole string exists. They are case sensitive as well.
$result['fmbushels_itemCode'] is from a sql query and always returns a code like the above in the text.
I'd appreciate any help on this. If someone knows a better way of doing this or a different command, I'd be willing to give that a shot as well :)
edit:
private function _fvShareBushels() {
$subject = file_get_contents(fvManager_Path . 'myfile.txt');
if (count($vShareArray) > 0) {
$vCntMoves = count($vShareArray);
for ($vI = 0;$vI < $vRunMainLoop;$vI++) {
sell $result['fmbushels_itemCode']);
}
}
}
This is a snippet of a big code. I had to rip most out because of post limitation. The area I could be working with is:
if (count($vShareArray) > 0) {
If I could make this something like:
if (count($vShareArray) > 0 && $result['fmbushels_itemCode'] **is not in** $subject) {
If you want to do line by line, use the file() function.
$f = file(fvManager_Path . 'myfile.txt');
foreach($f AS $line){
// $line is current line at file
}
I'm not to sure if you understand completely how preg_match works. The first parameter is the regular expression pattern, the second is what you want to match the pattern to, and the third is an array of matches. So for every valid pattern matched in the second parameter a new index on the array is created.
I'm not 100% on what you're trying to accomplish. Are you trying to see if the $result['fmbushels_itemCode'] exists in the file?
If the above is the correct case you simply just need to do something like:
$f = file('myfile.txt');
array_map('trim', $f);
if(in_array($result['fmbushels_itemCode'], $f)){
// success
}