I am currently working on my own shoutboxes using PHP, MYSQL and Jquery.
When a user has entered the shoutbox a message appears saying:
X has entered the shoutbox.
I do not want to store all visitors / users in MYSQL rows and so I was thinking I would need an array with a foreach script.
I'm not too sure how I should go about doing this, can someone please point me in the right direction?
Thank you
I assume you plan on storing this data in session? Depending on how you have session configured on your server, you may still be storing this data in a database (although the development effort may be less as you won't have to roll your own SQL to manage state).
The PHP manual has a section on arrays that sounds like it would be worth your time to read: http://php.net/manual/en/language.types.array.php. The manual has examples of adding objects to the array as well as looping through an existing array.
You could use a $_session variable, like when a user entered the shoutbox $_session->users[] = $user. $_session->users should be an array where you keep only their ids.
Related
I have a panel I'm making that will use session data from another forum to give it permissions. Basically when the user logs into our forum and the session and trust is created on the forum, they can click on the panel and the panel will check their browser cookie for the session id and trust id. It then takes that trust id and checks the forum's database for the user id associated with that trust. Then takes the session id and verifies that it belongs to that user id. The issue is that when I get the session id, the associated user id is part of a blob that i have to cast in order to get the data from the field. So I get a result like this:
('7c64c90413beb7d139c64ccc8b13380b',
'a:12:{s:12:"sessionStart";i:1454075264;s:2:"ip";s:4:"b???";s:11:"sessionCsrf";s:16:"-2Yx13nBLdstUj4H";
s:7:"user_id";i:20;
s:13:"password_date";i:1453353041;s:16:"previousActivity";i:1454072099;s:13:"trophyChecked";b:1;s:16:"promotionChecked";b:1;s:16:"dismissedNotices";a:0:{}s:15:"lastNoticeReset";i:0;s:13:"canAdminUsers";b:1;s:20:"userModerationCounts";a:2:{s:5:"total";i:0;s:13:"lastBuildDate";i:1454075264;}}'),
I know there is a lot there, but I singled out the part that matters to me. The first column returned is the session id, which im using to verify the user id, but the user id is in the middle of that all that crap in the second column. So you can see where I single out the definition, what I want to do is just assign that "20" after "user_id;i:" to a variable and discard the rest. I'm sure this is simply done, but at this point I think I'm just nuking it out and spinning wheels. I was thinking explode, but the structure of that data seems like that's not an option.
That data is simply the result of a PHP serialize() call. You can pass it to unserialize(), which will provide you with an array containing the values.
<?php
$str = 'a:12:{s:12:"sessionStart"…etc…etc…i:1454075264;}}';
$arr = unserialize($str);
var_dump($arr['user_id']);
In case you’re trying to extract the value from within MySQL alone, for some reason I’ve done something similar with an awful query containing lots of nested SUBSTR() and LOCATE() just two weeks ago. I wouldn’t recommend it. Especially because in my case I was doing a one-off reporting query, while you’re trying to do authentication with it. People might try to use specially crafted cookies to circumvent your string extraction and gain illegitimate access.
Im using functions for logging in a user, When they login but fail either by no captcha sent, failed captcha or failed login it will give there IP a Try. When they reach 5 tries they get blocked from the login page for approximately 1 hour. I have a function that updates the MySQL Column to increment there try count and last try date. But from looking at PHP's documents it states:
Note: The increment/decrement operators only affect numbers and
strings. Arrays, objects and resources are not affected.
My function gets the try count from the Database and then tries updating it. My SQL result for fetching the Try count is by default an Array because of how PDO works. So how can I efficiently increment an array?
I was thinking of doing a foreach condition and use the .=opperator to save it to a string and from there increment. But is that really the most efficient way?
Thank you.
P.S: I'm not showing any example code e.t.c because this question is simple enough. I have searched around on here and couldn't find a proper answer.
To understand why your question is wrong, you have to understand what an array is.
An array is just a "bag" that holds other variables. so, your question sounds like "How can I pay for a two beers with my pocket?". The thing is, you can't pay with a pocket. you have to take the cash out of the pocket and then use that cash.
Exactly the same thing goes with arrays: you have to extract the returned data from array, and then you are free to perform any operation on its contents. On the contents, remember, not on the bag.
But for the efficient solution, go for the other answer, which solved your initial problem the right way - without the need of selecting any arrays at all.
And just a side note
MySQL result for fetching the Try count is by default an Array because of how PDO works.
As a matter of fact, PDO can work in many different ways. For example, it can return scalar values all right.
You can increment it in an update query directly. When you want to add a try, simply:
UPDATE `tries` SET `tries` = `tries` + 1 WHERE `ip` = '127.0.0.1';
Just replace the IP with the actual IP.
Just to add..
IMO you should be using a separate table for incorrect login attempts. There are many reasons for this, but one of the important is that any attack is likely to rotate usernames and not only passwords in the attempt.
Having a separate table that records all incorrect logins allows you to much more easily query for an amount of incorrect logins in xx time. Incorrect logins attached to a user limits your ability to detect DoS and brute force attacks coming from scripted sources as you can only look at the username attempted if it actually existed in the first place.
However, you can relate a field in the table to the users ID, so that you can track users independently, then on successful login, the records that relate to that user could be deleted.
To give you a working example. I have built in the following functionality into the commercial Symfony project that I work on on a daily basis.
table example
userID --- foreign key (not mandatory)
IP --- mandatory
timestamp --- mandatory
we query the data like this:
Overall failed attempts for a particular subdomain (we have lots of them in use using the same system)
the system is used in schools, so we have to cater for naughty students!
Overall failed attempts in the last minute
system sleeps for a random time based on a base value x the amount. (a bit of a hacky way to try to trip up script attacks)
Overall attempts for a particular user
similar to your example.. compares to preconfigured amounts then warns/disables users accordingly. If it blocks sends an email to the helpdesk team.
this is by no means a suggested list, or an example of what should be done.. its merely what we decided on our applications circumstances.
The point is, without a separate table much of this wouldn't be possible.
I have a simple followers/following system set up within my app.
What would be the best way to store a complete array of 'users following' during a session so that I don't have to query the database multiple times throughout.
To clarify: When a user logs in once they have been authorized I query the database, get a full list of users that the logged in user is following and ultimately store it as a JavaScript variable. This way throughout the site, as the user navigates around I can constantly check the following status against any other user they may come across.
This query is only performed once when the user loads the full page, while navigating around it is not repeated.
This works well for javascript generated content i.e user hovercards etc...
However I would like to store this array (of only userid's) in PHP itself so that I can prevent further queries to the following table while generating content server side that requires a 'follower/following' check to be performed.
What would be the best way to do this?
Please bare in mind that the results are cached in memcached but if I can avoid any lookups at all and have a consistent array to check against that would be great.
Thanks in advance
So let me get this right, you want to store this list so it isn't queried on each page?
First I would recommend you only perform this query on pages that need this data and second I would say that on these pages you don't try this.
Imagine a user stops following or starts following. Some complex cache calculator or event bubbler programmed into your own PHP app to purge the foreign session of data (which is bad, the user has access to data that is not their own, a session infact) could be tiedious with security and performance.
The better thing to do is to perform the query again for each new page. This would be much easier, probably more performant and wouldn't be micro-optimising.
Edit
If you are picking out 10k rows on one page then you might be doing something wrong. You might be looking at it from the wrong perspective.
Store it in the session variable.
http://php.about.com/od/advancedphp/ss/php_sessions.htm
https://www.google.se/search?q=learning+sessions+php
UPDATE
Store the current user in a session and add it to the queries you are already doing to fetch the popup information and add that it tests if the popups person follows the current user.
The two ways that come to mind would be to just write joins with well placed indexes each time, which you've said you don't want to do, and just a simple array in the session, which would probably look something like this:
if (!isset($_SESSION['following']) {
$following = $user->getFollowingIds(); //some query in here to get an array of ids
$_SESSION['following'] = $following;
$_SESSION['following_str'] = implode(',', $following);
}
Then whenever you want to pull all of the statuses for the people that $user is following you can write a query, something like this:
$query('SELECT status.* FROM status WHERE user_id IN (' . $_SESSION['following_str'] . ')'); //not sanitized or safe but you get the idea
I am writing an application which shows a user one thing to vote on, at a time. I have a MySQL table which contains these things. Right now I have it set up so that upon login, I query my database to get a limited number of these things, and then I use PHP to turn that into an array. After a user submits a vote, the thing they've already voted on is 'unset' from the array. When the new array size is one, I query my database to create a new array.
Is this a 'bad' way to do it? Should I instead just query my database to get a new thing for the user to vote on after every time they submit a vote?
Any help/suggestions appreciated.
This will likely get closed because it's subjective...
IMHO, it's all a matter of how you want it to function. Typically, in standard programming, I suggest loading everything up-front so that once loaded, the user's experience is very smooth and without loading.
In Web programming, however, using AJAX or something similarly asynchronous to dynamically modify/rebuild the array as you need is certainly acceptable, especially if the end result is functioning in a way you're happy with.
Bottom line: Either way will work - it depends on your needs.
Reducing database interactions will typically make your web app perform better. If performance is ever going to be a concern, this could help there. On the other hand it makes the code a bit more complicated, which could impact maintainability in the future.
In the end, it's a trade off. As long as everything is done in a clear and logical way, either approach should be ok.
This answer is based on this answer.
Cha uses arrays in storing login -info in contrast to my code.
It likely improves the efficiency in searching the login -data and keeps your data organized.
However, I am not sure whether this is the best data structure in storing all pieces of the login info.
My solution always fetches passhash from the database when needing the info and then destroyes it after the use, instead of storing it to the array in PHP for session. It also keeps all variables as independent variables. It uses heavily PostgreSQL in contrast of data manipulation by a scripting language.
Which are the pros and cons of using arrays in PHP for storing login data?
[edit]
I use the following code at the moment in getting the data from the database.
$result = pg_prepare($dbconn, "query22", "SELECT passhash_md5 FROM users
WHERE email=$1;");
$passhash_md5 = pg_execute($dbconn, "query22", array($_REQUEST['email']));
So it should be changed to PDO to make it better. Studying that.
The Pros of keeping data using a Session based login system is the fact that it doesn't hit the database very hard. Databases are a single entity, as in you connect to the database and a table. If you have millions of pages doing that, things can get tricky.
On the other hand, storing stuff in a session array, you have a lot of small files that are each their own separate entity, and each is only accessed once per page view by that specific visitor.
Session files also are smaller and easier to grab everytime. In a database, you have to search through a lot of records (if you have a lot of users), and find the specific record. In contrast, sessions simply grab the data in a specific file for that specific session.
Going from what Ryeguy added. I would highly advise against select every record, and then doing a while loop through them to find the right user. I'd suggest look at the Where statement, so you can have the database only give you the record that matches the user's username.
That was just a matter of preference, it really doesn't matter. One possible use is a sort of namespacing, though. Imagine you have two forms on one page: login and register. Obviously, at the very least, these forms would both have a username and password field. To differentiate between the two, you could have the fields named register[username] and login[username] (ditto with password), that way you could tell which is which.
Also, please don't use the SQL query in your other question. Do you realize you're returning the ENTIRE user table every time someone logs in? Imagine what happens if you get 100,000 users on your site..your logins would take minutes and your database would be brought to its knees. I think you should learn some basic sql before tackling this.
Also, look into using PDO instead of the procedural database functions. PDO is cleaner, easier, and can be faster in some cases.