Random Content Array seems stuck - php

I have a random content script that has worked perfectly but now seems to have a glitch.
It's the "Spotlight On:" story on the upper lefthand corner at http://fiction.deslea.com/index2.php and the code is as follows:
$storyspotlights = array("bluevial", "biophilia", "real", "edgeofreality",
"limitsofperception", "markofcain", "spokenfor", "closer",
"feildelm", "purgatory", "elemental");
$randomstoryID = array_rand($storyspotlights);
$randomstory = $storyspotlights[$randomstoryID];
switch ($randomstory) {
case ($randomstory == 'closer'):
$storyspotlightheader = "<div class='storyspotlightheader'>Closer</div>";
$storyspotlighttext = "snip";
//some stories snipped
case ($randomstory == 'bluevial'):
$storyspotlightheader = "<div class='storyspotlightheader'>The Blue
Vial</div>";
$storyspotlighttext = "snip";
break;
//more stories snipped
}
print($storyspotlightheader);
print($storyspotlighttext);
My problem is - all the stories from Blue Vial to Spoken For appear when you refresh the page, in random order (although Blue Vial seems to stick a fair bit). These were the stories in the script originally.
Since then I have added the last four to the array and the content generation switch case fragment, but these last four stories never, ever appear in the randomiser. I've literally sat and refreshed for hours. I've confirmed over and over that the updated script is on the server, and even deleted and re-uploaded it.
I did try unset and also $storyspotlights = array() at the beginning of the script at various stages of troubleshooting, but to no avail. I also tried moving the new stories to the start of the array - no change there either.
What am I missing?

It's surprising this works at all. That's not how you use switch..case.
switch (<value to compare>) {
case <value to compare against>:
...
}
That means you write this:
switch ($randomstory) {
case 'closer':
...
}
With what you've written it's actually executing like:
if ($randomstory == ($randomstory == 'closer')) ...
Also make sure you have not actually forgotten some break statements, which would make the code fall through to the next case and indeed make certain cases "more sticky" than others.
Also, I'd simplify the whole thing to this:
$stories = array(
array('header' => '...', 'text' => '...'),
array('header' => '...', 'text' => '...'),
...
);
$story = $stories[array_rand($stories)];
echo $story['header'];
echo $story['text'];

Related

Trying to use spaces in an array of search variables, but not getting the expected output / results

I cannot seem to get this working. I am trying to modify a very old script (of our late technician and close friend) which we use to be used for searching servers with which OS being used. This consists (as far as I can tell) out PHP and SMARTY.
I already tried escaping the content with slashes and using backticks. But it simply does not work. I really have no idea where to look. Below are the original two pieces of code (I couldn't find more parts for it, or I have overlooked).
Piece of PHP code from the 1st PHP-file:
$values['osname'] = array( '-' => 'no choice',
'5' => 'CentOS 5.x',
'6' => 'CentOS 6.x',
'7' => 'CentOS 7.x',
);
Piece of code from the 2nd PHP-file:
$osname = intval(Common::GPvar('osname'));
$_SESSION['form']['serverselect']['osname'] = $osname;
if ($osname != '-') { $where .= " AND dsh.sumup LIKE '%OS: CentOS ".$osname."%'"; }
This is being used in a search form, so when I select "CentOS 6.x" it will display all servers which have the text OS: CentOS 6.10 in it.
Now what I am trying to achieve is to make the following to work:
$values['osname'] = array( '-' => 'no choice',
'CentOS 5' => 'CentOS 5.x',
'CentOS 6' => 'CentOS 6.x',
'CentOS 7' => 'CentOS 7.x',
'Virtuozzo 7' => 'Virtuozzo 7.x',
);
I tried to escape the content, as I mentioned above, however that didn't work. So I am guessing the coding in the 2nd PHP-file also needs some adjusting. So I tried removing certain stuff, like "CentOS", "%" and several other things. But it does not work. The result is that, on a search, I am getting all servers being displayed (no matter what OS is on them).
I guess I did correctly on escaping the variables in the array, but the 2nd piece of coding is not compatible for some reason with the requested search input?
Anyone has an idea what I am doing wrong here?
You can remove intval(...) because intval will turn strings into integers
https://php.net/manual/en/function.intval.php
$osname = Common::GPvar('osname');
The whole code
$osname = Common::GPvar('osname');
$_SESSION['form']['serverselect']['osname'] = $osname;
if ($osname != '-') { $where .= " AND dsh.sumup LIKE '".$osname."%'"; }

Miltiple if codes dont work together? (php)

I have a series of if codes that need to be put together but the code acts weird and chooses the last if code.
if($boardid='1'){ $altboard='13' and $title='Archives' ;}
elseif($boardid='2'){ $altboard='14' and $title='Archives' ;}
so this code turns out to work, but it cant be repeated to finish the rest of the codes
the code that doesn't work is:
if($boardid=='1'){ $altboard='13' and $title='Archives' ;}
if($boardid='2'){ $altboard='14' and $title='Archives' ;}
if($boardid='3'){ $altboard='15' and $title='Archives' ;}
if($boardid='6'){ $altboard='16' and $title='Archives' ;}
if($boardid='7'){ $altboard='17' and $title='Archives' ;}
and there is more if codes to add, but i didn't add them, as it only uses whatever turns out to be the last of the lines regardless of boards, even though it clearly recognizes the boards. so what gives and how do i make a series of if codes work together? I have another file with the exact same thing and it reacts the same. If then elseif for the rest of the code doesn't work and neither does alternating if and else if.
putting two equal signs Works fine with The above mentioned code but not with the second mentioned code which is this
if($wrong=='0'){$prize='1000';}
if($wrong=='1'){$prize='700';}
if($wrong=='2'){$prize='500';}
if($wrong=='4'){$prize='200';}
if($wrong=='5'){$prize='100';}
Unlike the last one where it keeps only the last code this one takes only the first one. so the prize always turns out to be 1000. any help here
You’re using = rather than == in your if conditions, which, supposing the value you assign is truthy, will always be true. Change your conditions to use == for comparison.
That said, you might want to consider using an associative array:
$data = array(
'1' => array('altboard' => '13', 'title' => 'Archives'),
'2' => array('altboard' => '14', 'title' => 'Archives'),
// ...
);
if(array_key_exists($data, $boardid)) {
$altboard = $data[$boardid]['altboard'];
$title = $data[$boardid]['title'];
}
Or, if the title is always “Archives”, pull that out:
$altboard_map = array('1' => '13', '2' => '14', /* ... */);
if(array_key_exists($data, $boardid)) {
$title = "Archives"; // consider moving out of the 'if' if applicable
$altboard = $altboard_map[$boardid]['altboard'];
}
should be like
if($boardid=='1'){ $altboard='13'; $title='Archives';}
if($boardid=='2'){ $altboard='14'; $title='Archives';}
if($boardid=='3'){ $altboard='15'; $title='Archives';}
if($boardid=='6'){ $altboard='16'; $title='Archives';}
if($boardid=='7'){ $altboard='17'; $title='Archives';}
Use switch case :
$title='Archives';
switch ($boardid) {
case 1:
$altboard='13';
break;
case 2:
$altboard='14';
break;
case 3:
$altboard='15';
break;
case 6:
$altboard='16';
break;
case 7:
$altboard='17';
break;
}

Why is this PHP foreach loop only executing once?

Trying to debug some issues with WordPress' notorious pseudo-cron. Thought about putting this on WordPressAnswers but I think this is less about WP and more a basic PHP question on a foreach that seems to never get past its first run. (Yes, definitely looked at a bunch of similar questions, but no love there, sorry.)
Here's the code, with 3 checkpoints where I added output for testing. I'm including the entire code of everything in the loop, just to be thorough, though most of it's probably beside the point. Checkpoints 2 and 3 never display for me, and checkpoint 1 only shows up once (i.e. on first iteration of loop). Not shown is where I'm outputting $crons, and count($crons) for good measure, to confirm that, yes, it absolutely has multiple elements.
foreach ( $crons as $timestamp => $cronhooks ) {
echo("<br>loop for timestamp " . $timestamp); // checkpoint 1
if ( $timestamp > $gmt_time ) {
break;
}
foreach ( $cronhooks as $hook => $keys ) {
echo("<br>loop for hook " . $hook); // checkpoint 2
foreach ( $keys as $k => $v ) {
$schedule = $v['schedule'];
if ( $schedule != false ) {
$new_args = array($timestamp, $schedule, $hook, $v['args']);
call_user_func_array('wp_reschedule_event', $new_args);
}
wp_unschedule_event( $timestamp, $hook, $v['args'] );
do_action_ref_array( $hook, $v['args'] );
// If the hook ran too long and another cron process stole the lock, quit.
if ( _get_cron_lock() != $doing_wp_cron ) {
echo("quitting!"); // checkpoint 3
return;
}
}
}
}
All the output I'm getting from this, despite my 5 elements, is:
loop for timestamp 1382968401
I'll be grateful for extra eyes on whatever I'm missing. I'm 95% sure this is WP core code, except my checkpoints, although for various reasons it's not out of the question that another programmer was mucking about in here in an end-run around our version control system. A whole other problem, obviously!
Assuming $gmt_time is current UTC time, then the timestamp 1382968401 will be greater (as of this writing):
$d = new DateTime('#'.'1382968401', new DateTimeZone('UTC'));
echo $d->format('Y-m-d H:i:s'); // output 2013-10-28 13:53:21
Which would explain why your loop breaks on the first iteration.
Well, foreach can't be wrong.
The only way your loop could do only one iteration is that it breaks. And that could only mean that the first $timestamp is greater than $gmt_time.
(There's also the return possibility near the bottom, but you already said you receive one line of text, so it couldn't have gone that way...)
I'm guessing that you want to just skip the iteration if the scheduled task is in the future. To do that, just change break with continue.

PHP - Count number of times string appears in file

I've got a file (leaderboard.txt) that looks like this:
funkystudios
funkystudios
funkystudios
gilletteracer74
axehairgel
Ferby123
dirdam
TheWu13
Expert_Assassin
TheWu13
ocanosoup
I want to be able to read this file, and print out the number of times each person appears in the file. (Also place in order of # of times in file)
funkystudios: 3
TheWu13: 2
gilletteracer74: 1
axehairgel: 1
(and so on)
I've tried various ways but It all came down to an issue when I would try to order them correctly... I'm guessing there is a pretty easy way to do this. (I'm new to PHP...)
EDIT:
I have gotten to this point:
foreach(array_count_values(file('leaderboard.txt')) as $person => $count)
echo "{$person} : {$count}<br />\r\n";
It doesn't order by the $count, but simply who comes up first in the file.
$counted = array_count_values(file('leaderboard.txt'));
arsort($counted);
foreach($counted as $person => $count)
echo "{$person} : {$count}<br />\r\n";

Handling unread posts in PHP / MySQL

For a personal project, I need to build a forum using PHP and MySQL. It is not possible for me to use an already-built forum package (such as phpBB).
I'm currently working through the logic needed to build such an application, but it's been a long day and I'm struggling with the concept of handling unread posts for users. One solution I had was to have a separate table which essentially holds all post IDs and user IDs, to determine if they've been read:
tbl_userReadPosts: user_id, post_id, read_timestamp
Obviously, if a user's ID appears in this table, we know they've read the post. This is great, except if we have thousdands of posts per day (which is more than possible in the system which is being proposed), and thousdands of users. This table would become huge within a matter of days, if not hours.
Another option would be to track the user's last activity as a timestamp, and then retrieve all posts made after their last activity was updated. This works in theory, but let's say a user is writing an extremely long post, and in the meantime several members also start new threads or reply to posts in other threads. When the user submits his new post, his last activity would be updated, and thus not match those made in the meantime.
Does anyone have experience with this, and how did you tackle it?
I've checked in phpBB and it seems that the system assigns a custom session to each user, and works on that basis, but the documentation is pretty sparse as to how this deals with unread posts.
Thoughts and opinions gratefully received, as always.
Sorry for the quick answer but I only have a second. You definitely do not want to store the read information in the database, as you've already deduced, this table would become gigantic.
Something in between what you've already suggested: Store the users last activity, and in conjunction with storing information of what they've seen in the cookie, to determine which threads/posts they've read already.
This offloads the storage to the client side cookie, which is far more efficient.
A table holding all user_ids and post_ids is a bad idea, as it grows exponentially. Imagine if your forum solution grew to a million posts and 50,000 users. Now you have 50 billion records. That'll be a problem.
The trick is to use a table as you said, but it only holds posts which have been read since the this login, of posts which were posted between the last login and this login.
All posts made prior to the last login are considered read.
IE, I last logged in on 4/3/2011, and then I log in today. All posts made before 4/3/2011 are considered read (they're not new to me). All posts between 4/3/2011 and now, are unread unless they are seen in the read table. The read table is flushed each time I log in.
This way your read posts table should never have more than a couple hundred records for each member.
Instead of having a new row for every post*user, you can have a field in the user-table that holds a comma-separated string with post-IDs that the user has read.
Obviously the user doesn't need to know that there are unread posts from 2 years ago, so you only display "New post" for posts made in the last 24 hours and is not in the comma-separated string.
You could also solve this with a session variable or a cookie.
This method stores the most recently-accessed postID separately for each forumID.
It's not as fine-grained as a solution that keeps track of each post individually, but it shrinks the amount of data that you need to store per user and still provides a decent way to keep track of a user's view history.
<?php
session_start();
//error_reporting(E_ALL);
// debug: clear session
if (isset($_GET['reset'])) { unset($_SESSION['activity']); }
// sample data: db table with your forum ids
$forums = array(
// forumID forumTitle
'1' => 'Public Chat',
'2' => 'Member Area',
'3' => 'Moderator Mayhem'
);
// sample data: db table with your forum posts
$posts = array(
// postID forumID postTitle
'12345' => array( 'fID'=>'1', 'title'=>'Hello World'),
'12346' => array( 'fID'=>'3', 'title'=>'I hate you all'),
'12347' => array( 'fID'=>'1', 'title'=>'Greetings!'),
'12348' => array( 'fID'=>'2', 'title'=>'Car thread'),
'12349' => array( 'fID'=>'1', 'title'=>'I like turtles!'),
'12350' => array( 'fID'=>'2', 'title'=>'Food thread'),
'12351' => array( 'fID'=>'3', 'title'=>'FR33 V1AGR4'),
'12352' => array( 'fID'=>'3', 'title'=>'CAPSLOCK IS AWESOME!!!!!!!!'),
'12353' => array( 'fID'=>'2', 'title'=>'Funny pictures thread'),
);
// sample data: db table with the last read post from each forum
$userhist = array(
// forumID postID
'1' => '12344',
'2' => '12350',
'3' => '12346'
);
// reference for shorter code
$s = &$_SESSION['activity'];
// store user's history into session
if (!isset($s)) { $s = $userhist; }
// mark forum as read
if (isset($_GET['mark'])) {
$mid = (int)$_GET['mark'];
if (array_key_exists($mid, $forums)) {
// sets the last read post to the last entry in $posts
$s[$mid] = array_search(end($posts), $posts);
}
// mark all forums as read
elseif ($mid == 0) {
foreach ($forums as $fid=>$finfo) {
// sets the last read post to the last entry in $posts
$s[$fid] = array_search(end($posts), $posts);
}
}
}
// mark post as read
if (isset($_GET['post'])) {
$pid = (int)$_GET['post'];
if (array_key_exists($pid, $posts)) {
// update activity if $pid is newer
$hist = &$s[$posts[$pid]['fID']];
if ($pid > $hist) {
$hist = $pid;
}
}
}
// link to mark all as read
echo '<p>[Read All]</p>' . PHP_EOL;
// display forum/post info
foreach ($forums as $fid=>$finfo) {
echo '<p>Forum: ' . $finfo;
echo ' [Mark as Read]<br>' . PHP_EOL;
foreach ($posts as $pid=>$pinfo) {
if ($pinfo['fID'] == $fid) {
echo '- Post: ' . $pid . '';
echo ' - ' . ($s[$fid] < $pid ? 'NEW' : 'old');
echo ' - "' . $pinfo['title'] . '"<br>' . PHP_EOL;
}
}
echo '</p>' . PHP_EOL;
}
// debug: display session value and reset link
echo '<hr><pre>$_SESSION = '; print_r($_SESSION); echo '</pre>' . PHP_EOL;
echo '<hr>[Reset Session]' . PHP_EOL;
?>
Note: Obviously this example is for demonstration purposes only. Some of the structure and logic may need to be changed when dealing with an actual database.
Phpbb2 has implemented this fairly simple. It just shows you all post since your last login. This way you don’t need to store any information about what the user actually has seen or read.

Categories