Issues validating HTML when using variables in URL - php

I am getting this error when running my page through the W3C validator:
= in an unquoted attribute value. Probable causes: Attributes running together or a URL query string in an unquoted attribute value.
Here is the code that is causing this error:
$prevPage = "?main=men&category1=1&pagenum=$prevp"."&lowRowNum=$prev_page_low".
"&highRowNum=$prev_page_high";
print("<a class='left' href=$prevPage>".
"Previous Page</a> ");
I am not getting any error like this in any of my other PHP scripts , so I am guessing it is something specific I am doing wrong here?
Can anyone see why this code is causing this error?
I have researched this and read that it may be down to HTML special characters? I am not sure..
Thank you

Simply try:
<a class='left' href='$prevPage'>
Notice the quotes. Always try to quote your attributes in HTML. Better practice would be to:
echo '<a class="left" href="' . $prevPage . '">' //etc etc;
Try not to echo the entire HTML string as you might get confused when using single vs. double quotes.

I would suggest using a combination of printf() and htmlentities() here:
printf(
'<a class="left" href="%s">Previous Page</a>'
, htmlentities($prevPage)
);
printf() takes a string and echos it after replacing specially-formatted tokens. In the above example, there is one token in the string, represented as %s.
When printf() runs, it replaces each token with a corresponding parameter. In the above example, the %s is replaced by the result of htmlentities($prevPage).
The manual page for sprintf() goes into more detail about how the tokens work and has many more examples (sprintf() and printf() are identical except that sprintf() returns the formatted string, while printf() outputs it directly).
To ensure that entities such as & are encoded correctly for markup validation, you should also make use of htmlentities().

Related

PHP echo returning blank value

So I am trying to link using data I got from a function but it keeps giving me a blank value for ID. Here's my code for what I'm trying to print
<h3 style="text-align: center;">Seller: <?php $sellername =
getNameFromListingID(); $id = getIDByUsername($sellername); echo "".$sellername."";?></h3>
The functions work properly, I have tried printing both of them and it works. They're in a file called getinfo.php, which I have
Include 'getinfo.php';
At the top of my document.
The link with the name works but I always get seller.php?id=, with no value after. Any clue as to why?
You're ending the href attribute too early.
<a href=\"seller.php?id=".$id."\">
This will put the $id inside the href attribute, where it belongs.
Use single quotes in PHP, it's a good practice to get into, and it's also slightly (a teeny tiny bit) faster for PHP to process. Why? Because, when you use double quotes, you're telling PHP that your string contains variables that may need to be evaluated.
So in truth, you don't even need the quotes around variables here.
echo "$sellername";
But doing it like this would be following a best practice.
And now you don't need to escape \" double quotes that HTML uses.
echo ''.$sellername.'';
Caution: It's also a very good idea to escape special characters in anything you're outputting into HTML markup. That avoids the potential for an XSS vulnerability. See: htmlspecialchars()
echo ''.htmlspecialchars($sellername).'';

How do I turn my query result into a link?

I am returning data from three columns and displayed it with:
echo "<p><h3><span class='tyler'>".$results['COL 2']."</span></h3>".$results['COL 4'].$results['COL 3']."</p>";
This works fine. COL 4 is an actual URL and I am trying to put it in an anchor tag with COL 3 as the anchor text:
echo "<p><h3><span class='tyler'>".$results['COL 2']."</span></h3>""<a href=".$results['COL 4']"/>".$results['COL 3']."</a></p>";
I am trying to use this code but it doesn't work. My assumption is that the problem has something to do with the back to back quotes after the closing h3 tag. How would I go about making this work?
It can get confusing to build large strings that are output to HTML. This is what you have:
echo "<p><h3><span class='tyler'>"
.$results['COL 2']
."</span></h3>""<a href=".$results['COL 4']"/>"
.$results['COL 3']
."</a></p>";
I've broken it up to more clearly reference what is going on. In the third line (starting with the close-span tag), you have two double quotes right next to each other. Further on, you have quotes opening the close-slash part of the tag, but not a string concatenation operator (.). Finally, you are confusing double and single quotes. You want:
."</span></h3><a href='".$results['COL 4']."'/>"
But a better way of doing this would be to split out your components:
$title = $results['COL 2'];
$href = $results['COL 4'];
$anchor_text = $results['COL 4'];
// Here you can add debugging statements to ensure you have the right values.
$paragraph = "<p><h3><span class='tyler'>%s</span></h3><a href='%s'>%s</a></p>"
echo sprintf($paragraph, $title, $href, $anchor_text);
This method uses sprintf to 'slot in' the strings you want. It allows you to be more clear about building the html, without worrying about what the specific 'dynamic' values are. There are, of course, many other ways of doing this sort of 'templating'.
An Aside on String Building in PHP
This line of code assigns a simple string to a variable in PHP:
$message = "Hello world!";
This line of code 'concatenates' three strings using the concatenation operator (which is a dot: .):
$html = "<p>".$html."</p>";
This line would yield an equivalent result:
$html = "<p>Hello world!</p>";
This line will yield an error:
$bad = "<p>""Hello world!""</p>";
The reason it yields an error is because the language will 'tokenize' the code into something like:
<variable name> <assign> <string> <string> <string> <end statement>
Except that, semantically, three <string>s in a row doesn't make sense. It needs an 'operator' between them, like so:
<variable name> <assign> <string> <concatenate> <string> <concatenate> <string> <end statement>
PHP knows how to 'parse' this string of tokens. It will know to evaluate each string, and then concatenate them together. An intermediate stage becomes this:
<variable name> <assign> <string (composed of three previous strings)> <end statement>
It knows this because the concatenation operator tells it how to combine those strings.
That brings us back to using the dot/concatenation operator:
$html = "<p>Hello world!</p>";
Now, HTML markup looks like this:
SO Help Page
And when PHP 'outputs' the final result, all it is doing is 'echo'ing or 'printing' a string to the HTML response. Given that, and given that PHP interprets a double quote as the 'end' of a string, how do you put strings into a variable, so it prints out like the HTML above? This won't work, because PHP doesn't know how to interpret http://... in this context:
echo "SO Help Page";
There are a few ways to get around this. You can 'escape' the double quotes:
echo "SO Help Page";
By inserting a \ in the string before the double quote you signal to PHP to not end the string token, and to therefore parse the whole thing as a single string.
Alternatively, HTML also accepts single quotes for it's attribute values. So you can do this:
echo "<a href='http://www.stackoverflow.com/help'>SO Help Page</a>";
Which yields this on the HTML response:
<a href='http://www.stackoverflow.com/help'>SO Help Page</a>
Regardless of which way you go, you have to remember that the PHP code does not magically know that you're building an HTML page: it is simply constructing and printing strings to the HTML response. You have to tell it when to ignore parts of the string.
My point above is that for long enough PHP scripts, this can become confusing. So breaking down the strings into manageable chunks, so you can see what you're inserting and where things (like quotes, open and close tags, etc.) are makes your life easier.

Appending a string to the end of a URL in a variable in PHP

So I have this code for a youtube link in a wordpress widget
$title = "<h5 class='widget_title sidebar_widget_title'><a
href='http://www.youtube.com/user/".$options['username']."'
target='_blank'>".$options['title']."</a></h5>";
So I'm trying to append
?sub_confirmation=1
after my youtube user name so that a subscribe confirmation comes up but wow I have tried everything and am just not a good enough coder yet.
You just insert the query string parameter to the string.
$title = "<h5 class='widget_title sidebar_widget_title'><a href='http://www.youtube.com/user/".$options['username']."?sub_confirmation=1' target='_blank'>".$options['title']."</a></h5>";
The reason this is possibly confusing to you is because the author of the code you're changing used " to tell PHP that the next sequence of characters form a string, and ' to tell HTML that this is the value for the href attribute (like <a href='youtube.com'>...</a>). This works because HTML supports both " and ', and it saves you the hassle of having to escape quotes.
Personally, I'd rather use ' for PHP-strings and regular " for HTML, but that's a matter of taste.

Single quotes turning url into twins?

Just noticed that when using single quotes to echo a basic link in php, the url repeats itself.
<?php
echo 'Link URL - Single Quotes<br />';
?>
The above code outputs the link as:
http://example.com/"http://example.com/"
Can anyone shed some light on the reason for this?
You shouldn't \-escape your " when you're using ' to surround the string as a whole. This couldn't create that output itself, but it might confuse a parser somewhere down the line, producing the problem. Try this instead:
echo 'Example.com<br />';
Use PHP to output dynamic data and leave the HTML out of it. This will save you hours of quotation frustration
?>
Example.com<br />
<?php
// carry on with the PHP
echo 'Example.com<br />';
outputs
Example.com<br />
The backslashes are included in the final output and most likely trip up the HTML parser.
You're escaping the double quotes. It isn't necessary when using single quotes and vice-versa.
<?php
echo 'Example.com<br />';
?>
The above code outputs the link as:
http://example.com/"http://example.com/"
No, it doesn't produce that output.
This is what you see in the browser when you put the cursor over the link and when you click on the link. It's part of the browser's job to resolve the relative and incomplete links, but what it shows to the user is, most of the times, not what it is written in the HTML code.
Use the browser's "View Source" functionality to see the HTML generated by your code.
The (invalid) HTML produced by your code is:
Link URL - Single Quotes<br />
The browser interprets \"http://example.com\" as the value of the href attribute. The HTTML attribute values can be either enclosed in quotes (") or apostrophes (') or unquoted at all and the quoting character must be the first non-space character after the equal sign (=). Because it finds a backslash (\) after the equal sign, it concludes the attribute value is not quoted and read everything until the first whitespace or until the tag ends (>) as the attribute's value.
The value \"http://example.com\" is not a valid URL and the browser handles it as an incomplete URL. An incomplete URL needs to be resolved to a complete URL in order to be used. It doesn't look like a relative URL (doesn't start with ..), it doesn't look like an absolute path without a host name either (doesn't start with /). The only way to resolve it is to treat it as a file name located in the same directory as the page that is currently loaded. Chances are that your offending code runs in a page located in the root of your website (http://example.com/index.php, for example).
I won't provide a fix for your problem here. The question already have plenty of answers that provide you various ways to avoid this happen.
However, take a look at the strings documentation page in the PHP manual. All you need to know is explained there.

Apostrophe issue

I have built a search engine using php and mysql.
Problem:
When I submit a word with an apostrophe in it and return the value to the text field using $_GET the apostrophe has been replaced with a backslash and all characters after the apostrophe are missing.
Example:
Submitted Words: Just can't get enough
Returned Value (Using $_GET): Just can\
Also the url comes up like this:search=just+can%27t+get+enough
As you can see the ' has been replaced with a \ and get enough is missing.
Question:
Does anybody know what causes this to happen and what is the solution to fix this problem?
The code:
http://tinypaste.com/11d62
If you're running PHP version less than 5.3.0, the slash might be added by the Magic Quotes which you can turn off in the .ini file.
From your description of "value to the text field" I speculate you have some output code like this:
Redisplay
<input value='<?=$_GET['search']?>'>
In that case the contained single quote will terminate the html attribute. And anything behind the single quote is simply garbage to the browser. In this case applying htmlspecialchars to the output helps.
(The backslash is likely due to magic_quotes or mysql_*_escape before outputting the text. I doubt the question describes a database error here.)
Update: It seems it's indeed an output problem here:
echo "<a href='searchmusic.php?search=$search&s=$next'>Next</a>";
Regardless of if you use single or double quotes you would need:
echo "<a href='searchmusic.php?search="
. htmlspecialchars(stripslashes($search))
. "&s=$next'>Next</a>";
(Notice that using stripslashes is a workaround here. You should preserve the original search text, or disable the magic_quotes rather.)
Okay I forgot something crucial. htmlspecialchars needs the ENT_QUOTES parameter - always, and in your case particularly:
// prepare for later output:
$search = $_GET['search'];
$html_search = htmlspecialchars(stripslashes($search), ENT_QUOTES);
And then use that whereever you wanted to display $search before:
echo "<a href='searchmusic.php?search=$html_search&s=$next'>Next</a>";
Single quotes are important in PHP and MySQL.
A single quote is a delimeter for a string in PHP, for example:
$str = 'my string';
If you want to include a literal quote inside a string you must tell PHP that the quote is not the end of the string. It is escaped with the backslash, for example:
$str = 'my string with a quote \' inside it';
See PHP Strings for more on this.
MySQL operates in a similar way. An example query might be:
$username = 'andyb';
$quert = "SELECT * FROM users WHERE user_name = '$username'";
The single quote delimits the string parameter. If the $username included a single quote, this would cause the query to end prematurely. Correctly escaping parameters is an important concept to be familiar with as it is one attack vector for breaking into a database - see SQL Injection for more information.
One way to handle this escaping is with mysql_real_escape_string().

Categories