Can anyone please explain me how is this happening? - php

I have created a page like account_details.php in which I'm counting the number of times the user visits the page. So for that I have created a file called count_session.php in which the code is like:
<?php
session_start();
if(!isset($_SESSION['counter'])){
$_SESSION['counter'] = 0;
}else{
$_SESSION['counter'] = $_SESSION['counter'] + 1;
}
?>
I include the above file in account_details.php page in which I want the user to see how many times he has visited and it works fine but I don't understand how does it work? I have checked using the echo message inside the first 'if' condition that is if(!isset) and it seems it does not enter that condition instead it enters the else part but then how come it's getting initialized by 0, but when the user visits the account_details.php page the message pops up like "You have visited this page for 1 times". How come it's calculating 0 + 1 when it's not yet initialized anywhere in the count_session.php file. Can anyone please tell me?

This has nothing to do with session variables, as it works the same way for regular variables.
If you write something like $a = $a + 1 and $a is not declared anywhere, PHP considers it as not set, which translates to 0 if cast to int (the same way it translates to false if cast to bool, but that's not relevant in this case). The reason why your variable is cast to int, is that PHP feels the need to, because you are trying to perform a mathematical operation on that variable.
To sum up: PHP detects that you want to add up 2 values, does something like intval($a) (but internally of course) and adds 1 to that. In addition, if you have notices enabled, this should throw you a notice.

Sessions are global to a site (as in hostname) because they are identified by an ID stored in cookies, which are by default sent back to to all URLs under a single domain name. You can restrict that further, but this is the default behavior.

Related

What are the limits on session names in PHP?

The PHP docs on session_name() say:
It should contain only alphanumeric characters; it should be short and descriptive (i.e. for users with enabled cookie warnings). ... The session name can't consist of digits only, at least one letter must be present. Otherwise a new session id is generated every time.
So it's clear you must have something non-numeric in there, but it's not quite clear what characters you can't have. The cookie spec itself denies ()<>#,;:\"/[]?={}, but that still leaves others that might be permitted but are not strictly alphanumeric. This is important because cookie security prefixes use - and _ in names like __Secure-PHPSESSID. So I had a rummage in the PHP source code at the session_name function – but I can't see that it does anything other than check it's a string. In practice, it works fine, but I'd be more comfortable knowing precisely why! For example, this works:
session_name('__Secure-PHPSESSID');
session_start();
$_SESSION['test'] = $_SESSION['test'] . "\n" . rand(0,100);
var_dump($_SESSION);
So what are the actual limits on PHP session names?
I got a bit further with this. The rules for a session name are defined in this validation function, which permits [a-zA-Z0-9,-]{1,256} (but not numeric-only). You can have commas and dashes in session names in addition to alphanumerics, so the docs are wrong on that. This function is called from an internal session_create_id function, which triggers a warning if the session name doesn't pass that validation.
Despite this, no warning is triggered when passing in a session name containing _. This is demonstrable:
<?php
ini_set('display_errors', true);
error_reporting(E_ALL);
session_name('__Secure-MySession');
session_start();
if (!array_key_exists('test', $_SESSION)) {
$_SESSION['test'] = '';
}
$_SESSION['test'] .= "\n" . rand(0,100);
var_dump($_SESSION);
echo session_name();
This works perfectly, triggering no errors or warnings, and shows a growing list of random numbers (showing that the session storage is working and therefore the cookies are too), and the second session_name call with no params shows the session name that we set:
__Secure-MySession
And the HTTP headers show that the script sets a cookie called __Secure-MySession:
I also tried naming the session My_Session, just in case PHP looks for explicit __Session- prefix, but that works just fine too. Other characters like # or ( do not trigger an error either; in those cases the session name is URL-encoded, which looks remarkably like this bug that was fixed quite a while ago. As expected, 123, works, but also URL-encodes the comma.
So while this demonstrates that having _ in session names works fine, I can't tell you why. I've asked elsewhere too, and if I find out, I will update this question!
Coincidentally, draft 06 of RFC6265bis expires today.

I still can't understand Optionals

I'm new to the Swift language and until this point i only worked in web development.
I tried to grasp the idea of optionals, but every time they present some situation where to use it, I still can't understand why they do so (or I might have a little idea, but still not sure.)
I read several articles about this and maybe I just got too confused about it along the way and got lost.
So let's present some examples. Let's say I have a registration form with a textfield for an e-mail. After the form is sent, in PHP I could do something like:
$mail = $_POST['mail'];
if($mail == "") {
echo "ERROR: The E-mail is empty";
} else {
// Do something more
}
If the textfield is empty, the value of $_POST['mail'] is an empty string. I can work with that and check if it is empty or not.
Now, if I understand correctly, in swift the value of that textfield wouldn't be an empty string, but actually a nil, right? Is this that kind of a difference why we need optionals? Because in comparison to PHP, in Swift I have to declare the type of that information each time and it doesn't know if that textfield passes strings or numbers?
Let's talk about another example. Lot of people in swift just declare a string as an optional, even if they put a value in it, like so:
let name:String? = "Gabriel"
If it already has a value, why make it an optional then? For me, it is just a normal constant with a value and I don't see the point of wrapping it into an optional.
If I don't know the name at the declaration, why can't i just type this?
let name:String = ""
and after that, I can use an if statement to check if it is empty or not
if name == "" {
print("ERROR: name is empty")
} else {
//Do something else
}
Did I get the idea with the textfield right or not?
Is there something I'm missing?
Thank You for any help!
EDIT (What got me understanding the concept):
What I got confused about the most was the simple fact, that for example a String can store only "text" and that if nil was something, it wouldn't be of type String, so therefore it couldn't be "stored" inside String of course.
Just in the same way, as I can't store text into an Integer — I can't "store" nil into a String.
But with Optional String I can use this "wrapper" that actually CAN "store" both types: string or nil. And that is what distinguish regular String from Optional String. It is this "wrapper" that has the ability to "hold" both these types until I need to use the actual value. (Now of course I understand, that nil is actually an absence of any value. I just used it in this way to illustrate the point)
Thank You everyone for Your help!
Imagine you ordered a playstation from ebay. The first thing you see is not the playstation, but a box. So, in this instance, the box is an optional. Let's write it down.
var playstation: Playstation?
The box can of course be empty. In order to use the playstation, we need to open the box. We have several ways to do that.
The safe way:
if let ps = playstation {
// if the box is not empty, and the PS is there
ps.play()
} else {
print("The box was empty :(")
}
The other way:
playstation?.play()
In this other scenario, we're only calling the play() method if the contents of playstation box are not empty. Downside is that you cannot display an error in case it fails.
What if you promised your friend that you'll play together on your playstation that will be here today. You're giving a guarantee that the playstation will be in the box. That's when you use this:
playstation!.play()
Problem with this approach, in actual programs, is that your app will crash if the contents of the optional are empty. Use "!" only if you can guarantee that it will not be empty (i.e. you assigned a value to the variable right before this)
So, to conclude, optionals are variables whose value can be either a specific type (i.e. String) or nil. You cannot assign nil to strongly typed variables.
var a: String?
var b: String
a = nil // this is ok
b = nil // this will not compile
Think of optionals like this :
An optional is a variable which can be empty something in the future or even now.
Making a variable an optional means it is wrapped as an enum.
Suppose there is a variable : var x : Int?, this means a variable named x of type Int, is not yet initialised and an optional.
This typically can be represented in layman terms as
Enum x(optional) // name of the variable{
case T: // some value
case nil: // no value
}
So when we assign a variable we can just assign it normally, but the value is stored in the case T of the optional enum variable of x.
x = 10 //
enum x(optional){
case T = 10
case nil
}
When we want to use it(get the value) we use a (?) or an (!)
These can be farther explained as
print(x?) // If there is any value inside of x, give it to me(in this case give me the value of x's case of T)
print(x!) // I dont care if there is any value inside of x or not, just give it to me anyway.
Hence if x has no value then printing (x!) will produce a crash, as x does not have a value inside of it.
? - safely unwrapping the optional
! - force unwrapping the optional
P.S - I know there are certain things I missed but this is the jist of Optional is this is meant only for explanatory purpose. Once you grasp this concept you can farther check out more documents on Apple's documentation here
Effectively,
let name:String? = "Gabriel"
is not very useful.
But
var name:String? = "Gabriel"
does make sense, as you can further on set to nil.
Optionals are very useful for returning value from function.
Consider a func that returns an Int.
If the value is not found, you could return a number (like very large negative) to notify value was not found. But there is a risk some day that the func does return this value (even unlikely).
Returning a nil let the function make it clear it did not find the value.
My understanding of optionals is that they are a type just like String, or an Int, or a Double. Optionals have associated values so an String? is an optional with a String associated to it. The optional can either contain a value which is a string, even an empty string or nothing at all, which to me is null. Check out the Stanford U IOS course on iTunes. Optionals are explained much better then I am able to.

Session Variables Disappearing in PHP

I came across some strange session behavior today while testing some things out. First off, I've been tasked to create a registration feature for a WordPress website. I've done a fair amount of work in WordPress in the past, but I've never done anything involving any server-side scripting languages.
I was testing out my work environment, which involves making sure that I'm able to connect to MySQL, making sure sessions are working, and basically just familiarizing myself with the setup.
When testing sessions, I did the following:
<?php
$timer = time();
$_SESSION[$timer] = $timer;
print_r($_SESSION);
?>
I was expecting on the first load of the page to see something like this:
Array
(
[1396745563] => 1396745563
)
... which is exactly what happened. On the second refresh, I wanted to see:
Array
(
[1396745563] => 1396745563
[1396745570] => 1396745570
)
... But instead, I saw:
Array
(
[1396745570] => 1396745570
)
Wow! The original session variable for timestamp 1396745563 was gone, and there was a new one in it's place.
My immediate reaction was that maybe a session_start() was missing, but that was not the case. Just to further convince myself that something was weird about this, I altered my code to look like this:
<?php
$timer = time();
$_SESSION['time_' . $timer] = $timer;
print_r($_SESSION);
?>
I thought that perhaps having a session variable with a timestamp for an index had some sort of special behavior (which might be the answer to this question for all I know).
This time, the behavior was exactly as I had expected. Each refresh of the page added on to the array print-out. After a few refreshes of the page, it looked something like this:
Array
(
[time_1396745663] => 1396745663
[time_1396745667] => 1396745667
[time_1396745671] => 1396745671
[time_1396745675] => 1396745675
[1396745570] => 1396745570
)
That oddball variable is the session data that carried over from my original attempt (I'm just being precise).
Can someone explain this extremely odd behavior? I can't think of anything obvious that I could have done that would have caused this.
Note: I doubt that this has anything to do with WordPress; I only included it to give a motive behind doing this.
The keys of $_SESSION adhere to the same rules as valid variable names in PHP. They must begin with a letter or an underscore, followed by any number of letters, numbers or underscores. Therefore, the output of time() can’t serve as a key unless it’s prefixed by at least one letter or underscore.
Add the line error_reporting(E_ALL); to your code and PHP will throw a notice like the following:
Notice: Unknown: Skipping numeric key 1396747512 in Unknown on line 0

PHP strcmp question

I have been writing a webcrawler program, and I am attempting to compare a previous url (for the last site visited) with a current url (the current or next site to visit). To do this I am using a strcmp function such as this:
array_push($currentsite, $source);
if (strcmp($currentsite[2], $currentsite[3])==0){
echo "redundancy";
crawlWebsite($originalsource);
}
where current site is an array of the previous sites and the current site. I am looping through new sites each time with recursion in the larger program.
However, every time I run a strcmp on the current site and the new site, even when the urls are identical, I get a result of -1. Does anyone know why this might consistently be happening?
Thanks.
even when the urls are identical,
If the two input strings are identical, strcmp returns 0, so your input strings are not identical. Check the contents of $currentsite.
BTW strcmp($a, $b) == 0 can be efficiently rewritten as $a == $b.
Probably the site you are testing contains something that makes it unique, like the current time or a hidden ID to save your session or something like this.
Anyway that will result in strcmp to not return 0. It would be bettor to have a function that gives you a percentage of equality so you can define a level above which you consider two sites as identical.

"ghost" form submissions

I have a 3-part registration form using PHP:
page 1 : collects info - has client & server side validation (for blank and invalid fields)
page 2 : collect more info - has server side validation (for blank and invalid fields)
page 3 : saves (db) and sends (email) the registration information
More info:
page 1 : saves all form information into session[registration] before going to page 2
page 2 : redirects to page 1 if session[registration][email] is blank
page 3 : redirects to page 1 if session[registration][email] is blank; destroys session after registration is successful
This has been working fine for the past months until yesterday when around 25 emails were sent to me, with few seconds interval for each. I also checked the database and those registrations were saved. And the registration information are all BLANK (except the auto generated fields like date_added)
I'm puzzled because the email sending and db saving are not supposed to work because of the redirection.
Do you have any idea as to what just happened?
Thanks
How are you checking that the data fields aren't blank before inserting them into the db. Make sure to use empty() to check that the field is blank. If you're using string comparison operator (ie. if ($str != "") ), it can cause unexpected results if the value of $str is false, null, 0, etc...
Edit:
empty() description from manual: http://us.php.net/manual/en/function.empty.php
Return Values
Returns FALSE if var has a non-empty and non-zero value.
The following things are considered to be empty:
* "" (an empty string)
* 0 (0 as an integer)
* "0" (0 as a string)
* NULL
* FALSE
* array() (an empty array)
* var $var; (a variable declared, but without a value in a class)
edit2:
isset() only checks if a variable was assigned a value. If the variable contains an empty string, isset() will return true, because even an empty string has a value ('\0' marks the end of a string in php).
isset() description from manual : http://us3.php.net/manual/en/function.isset.php
isset() will return FALSE if testing a variable that has been set to NULL. Also note that a NULL byte ("\0") is not equivalent to the PHP NULL constant.
comment from manual :
isset doesn't reliably evaluate variables with blank strings (not necessarily NULL).
i.e.
$blankvar = ""; // isset will return true on this.
This is a very common pitfall when handling HTML forms that return blank text fields to the script. You're better off doing this:
if ($var != "")
return true;
else
return false;
This more of a programming practice rather than the function's shortcomings. So if you have a habit of initializing variables you're likely to run into problems with isset() if your code or php project become very large.
The problem is definitely in page 3. As an educated guess I would say, that your "blank"-check if flawed.
You should use ie. a good regexp to test if the email is valid and make sure to remove whitespace before checking the length of the fields (ie - a space is not the same as an empty/blank field)
Is it possible that all those emails were generate by a bot crawling your site?
Can you reproduce the problem by calling curl on any of your pages?
Do any actions require a POST, or are you taking action with a GET?

Categories