Main purpose is to get all categories listing from database by passing variables to url and show it to the main page.here i have omitted some code bt i tried to clarify.
1.can I exclude encodeHtml() method, too difficult for me to understand
2.i am not getting specially this part of code and having my head for 4 days
foreach($cats as $cat) {
echo "<li><a href=\"/?page=catalogue&category=".$cat['id']."\"";//here id is 'category id' from database. this full line will echo what?
echo Helper::getActive(array('category' => $cat['id']));//it will output what ?
echo ">";
echo Helper::encodeHtml($cat['name']);//as from ur answer can we omit encodeHTML() method and use htmlspecialchars($cat['name']); instead ?
echo "</a>
3.any easier solution will be more appreciated
in our database we have 'id' and 'name' of catagory listing
please check below for reference
/*below is the code in header section of template */
<?php
$objCatalogue = new Catalogue();// creating object of Catalogue class
$cats = $objCatalogue->getCategories(); // this gets all categories from database
<h2>Categories</h2>
<?php
foreach($cats as $cat) {
echo "<li><a href=\"/?page=catalogue&category=".$cat['id']."\"";
echo Helper::getActive(array('category' => $cat['id']));
echo ">";
echo Helper::encodeHtml($cat['name']);
echo "</a></li>";
}
?>
/*below is the helper class which is Helper.php */
public static function getActive($page = null) {
if(!empty($page)) {
if(is_array($page)) {
$error = array();
foreach($page as $key => $value) {
if(Url::getParam($key) != $value) //getParam takes name of the parameter and returns us the value by $_GET
{
array_push($error, $key);
}
}
return empty($error) ? " class=\"act\"" : null;
}
}
//CHECK THIS LINE BROTHER
return $page == Url::currentPage() ? " class=\"act\"" : null;// url::currentPage returns the current page but what is 'class =act ' :(
}
public static function encodeHTML($string, $case = 2) {
switch($case) {
case 1:
return htmlentities($string, ENT_NOQUOTES, 'UTF-8', false);
break;
case 2:
$pattern = '<([a-zA-Z0-9\.\, "\'_\/\-\+~=;:\(\)?&#%![\]#]+)>';
// put text only, devided with html tags into array
$textMatches = preg_split('/' . $pattern . '/', $string);
// array for sanitised output
$textSanitised = array();
foreach($textMatches as $key => $value) {
$textSanitised[$key] = htmlentities(html_entity_decode($value, ENT_QUOTES, 'UTF-8'), ENT_QUOTES, 'UTF-8');
}
foreach($textMatches as $key => $value) {
$string = str_replace($value, $textSanitised[$key], $string);
}
return $string;
break;
}
}
Firstly, in your URL (/?page=catalogue&category=) you don't need to put &, as this is an HTML entity for actually displaying an ampersand in a web page. Just use /?page=catalogue&category=.
Secondly, you can use urlencode() to prepare strings for sending in the URL, and urldecode() on the other end.
In answer to your first point you just need to make sure that ANYTHING from the user (whether via $_POST or $_GET) is sanitized, prior to being used in code, output to a web page, or used in database queries. Use htmlspecialchars() for cleaning before outputting to a web page, and prepared statements prior to entering user input into a query.
In answer to your second point please read the documentation in the links I have provided above. Just reading the documentation on htmlspecialchars() will help you a lot.
Hope this helps.
Alright then.
<?php
foreach($cats as $cat) {
echo "<li><a href=\"/?page=catalogue&category=".$cat['id']."\"";
echo Helper::getActive(array('category' => $cat['id']));
echo ">";
echo Helper::encodeHtml($cat['name']);
echo "</a></li>";
}
?>
Im just going to kindof skim through it, because honestly if you really want to learn all this you should probably google the shit out of every piece of code you don't understand, it's the way we all learn things.
< ?php announces some php script to follow. And as you can see, there does follow some php code after.
foreach is a way of getting each element from an array or list and doing something to that element.
echo sends whatever string comes after it to the page, or whatever is listening to its output. In this case, it looks like the echo's are printing some <li> list item with an <a> anchor in it.
Helper::getActive(): Helper is some class that is defined somewhere, :: is syntax for calling a static function that belongs to the class (Helper in this case). getActive is the function name.
array('category' => $cat['id'] is a piece of code that creates an array with 1 element in it, being one with key 'category' and a value of whatever is in $cat['id'].
By looking at getActive: it looks like it's a function that checks the url for some value so it can determine which page to display. It also checks if the url contains errors.
By lookingat encodeHtml(): it looks like it's a function that makes sure that whatever text you're trying to put on the screen, isn't something that could cause harm. In some situations, people will try to make your server print javascript that could harm the user (by sending personal data to somewhere). The encodeHtml() will ensure that no such thing can be done by stripping certain characters from the text you're about to send to the page.
USE GOOGLE.
Related
I have a strange situation that I've never encountered where the returned HTML from my class methods doesn't output in the correct structure. For some unknown reason, everything is nested inside the HTML within the first loop, second loop, etc.
index.php
<body>
some html...
<div class="usb-port-container">
<?= $generate->output('short_name',id,'hostname'); ?>
</div>
some html...
<div class="usb-port-container">
<?= $generate->output('short_name',id,'hostname'); ?>
</div>
some html...
</body>
class.generate.php
function __construct() {
$this->getCopy = new getCopyData();
$this->getDrive = new getDriveData();
$this->helper = new helper();
}
function output ($short_name,$id,$hostname) {
$portCount = $this->getCopy->portCount($hostname, 'total');
for ($port = 0; $port < $portCount; ++$port) {
if ($this->getCopy->probePort($hostname,$port)) {
$default = $this->usbPortDefault($short_name,$id,$hostname,$port);
return $default;
} else {
$details = $this->usbPortDetails($short_name,$id,$hostname,$port);
return $details;
}
}
}
function usbPortDefault($short_name,$id,$hostname,$port) {
$port_details = '<div>
<div>----</div>
<div>----</div>
</div>';
return $port_details;
}
function outputRecords($hostname,$port) {
//get records data from database
$records = $this->getCopy->records($hostname,$port);
//create empty variable for HTML
$records_html = "";
foreach ($records as $key => $value) {
if ($value) {
$records_html .= '<div><span class="copy-group">' .$key. '</span><span class="copy-instance">' .$value. '</span></div>';
} else {
return '<div>Unable to get any group or instance</div>';
}
}
return $records_html;
}
function usbPortDetails($short_name,$id,$hostname,$port) {
$port_info = '';
$port_info .= 'bunch of HTML';
$port_info .= $this->outputRecords($hostname,$port);
$port_info .= 'bunch of HTML';
return $port_info;
}
My best guess as to the problem, is that there is an issue with the way I am returning the HTML or something with output buffering. I actually don't know if I need it within my class, but I've taken it out and issue is the same. I've also tried adding output buffering to index.html.
Here is a snippet of the source HTML. The first discrepancy I notice is that the <div class="server-details"></div> highlighted in blue doesn't belong there, it should be inside <div class="dc-container"></div> and adjacent to the prior <div class="server-details"></div>. After port-data-left should be port-data-right but it's nowhere to be found. I'm almost convinced at this point that there's a missing closing tag somewhere but I can't find it. It's been several years since I seriously did any development :D
EDIT: After further investigation, it appears that the final $port_info is not outputting and may be causing this problem. Is there an issue with $port_info .= $this->outputRecords($hostname,$port); being there?
Since you reuse you object instance using $generate, the constructor and destructor methods are only called once in this script.
The constructor starts a new output buffer using ob_start(), which means everything outputted by the output method will be buffered until you flush it.
The issue is, the flush only happens in the destructor, with ob_end_flush(), which is only executed once, after the last output call.
Because you echo the result of the method and start a buffer at the same time, the output must indeed be weird and some nesting / repetition occurs because the next output still adds to the buffer.
As pointed out in the comment, the easiest solution is to turn off the output buffering in the class.
You also need to clear $port_info at the beginning of the method to make this work, although it should be fine, unless $port_info is a global var?
This was probably not cleared in the initial Class in order to make it work when called several times, to concatenate the results (and buffer them, before outputting them all at once)
A good usage of buffers in the middle of a page is to redirect the output of a function to a variable.
For example, you could have a function that echoes code but you don't want it echoed.
You could then do something like:
Some HTML
<?php
ob_start();
call_to_some_function_that_normally_outputs_code();
$myvar = ob_get_clean();
?>
Rest of the HTML
I have a sql query that I store in a variable and I displayed. I get the contents of this with file_get_contents from another file, I would like to recover some of this code (which is html) in order to make link. More precisely retrieve the id.
My api.php
$base = mysql_connect ('localhost','root','');
mysql_select_db('administrations', $base);
if(isset($_GET['cp']))
{
$sql = 'SELECT NOM_organisme, ID_organisme
FROM organismes
WHERE code_postal LIKE "%'.$_GET['cp'].'%"
ORDER BY NOM_organisme;';
$req = mysql_query($sql) or die('SQL Error !<br>'.$sql.'<br />'.mysql_error());
}
while ($data = mysql_fetch_array($req))
{
echo '<p id="'.$data['ID_organisme'].'"'.
$data['NOM_organisme'].'</br>'.
$data['ID_organisme'].'</p></br>';
}
I want to get the id="I WANT THIS".
And my index.php (part of my code that retrieves the contents).
if(isset($_POST['cp']))
{
$api = "http://mywebsite.fr/api.php?cp=".$_POST['cp'];
$var = file_get_contents($api);
echo $var;
}
How can I get the id="" in my index.php ?
please look at php get documentation. you need to link to your script with url parameters and access them in your php code.
http://php.net/manual/en/reserved.variables.get.php
echo ''.$data['NOM_organisme'].'</br>'.$data['ID_organisme'].'</br>';
php
if(isset($_GET['id']))
{
$api = "http://mywebsite.fr/api.php?cp=".$_GET['id'];
$var = file_get_contents($api);
echo $var;
}
if you dont want to use url parameter you can use post values
http://php.net/manual/en/reserved.variables.post.php
I understand what your trying to do, but dont find it logical without knowing the purpose of this tiny code :)
Do you have a link or some sort?
Basicly what i should do is:
$base = mysql_connect ('localhost','root','');
mysql_select_db('administrations', $base);
if(isset($_POST['cp']))
{
$sql = 'SELECT NOM_organisme, ID_organisme FROM organismes WHERE code_postal LIKE "%'.$_GET['cp'].'%" ORDER BY NOM_organisme;';
$req = mysql_query($sql) or die('SQL Error !<br>'.$sql.'<br />'.mysql_error());
while ($data = mysql_fetch_array($req))
{
echo '<p id="'.$data['ID_organisme'].'"'.$data['NOM_organisme'].'</br>'.$data['ID_organisme'].'</p></br>';
}
} else {
echo 'show something else';
}
If I get you correctly, you are
Sending a GET request in index.php using file_get_contents() to your website.
The website (api.php) performs an SQL query and prints the result in HTML.
index.php takes this HTML output and stores it in the variable $var.
You want to retrieve all values contained inside the id attribute of the paragraph.
In this case, you probably want to use regular expressions. preg_match_all seems to be appropriate. It should work for you like this:
$out = array();
preg_match_all("/id=\"([^\"]*?)\"/U", $var, $out);
foreach ($out as $value) {
echo 'I found some id ' . htmlspecialchars($out[$value][2]) . '<br />';
}
And additionally:
A decent HTML parser would be much more appropriate in this case (eg. it would not match id="X" in flow text).
Your PHP code is vulnerable to SQL injections.
You should sanitize plain text to HTML appropriately.
First of all, you should try to display your API reply as a JSON-string, this is much more convenient.
If you still want to use your api.php, you first need to close your opening paragraph! You did forget a '>'!
echo '<p id="'.$data['ID_organisme'].'">'.
$data['NOM_organisme'].'</br>'.
$data['ID_organisme'].'</p></br>';
Then you need to parse your paragraph.
You can do it like that:
if(isset($_POST['cp']))
{
$api = "http://mywebsite.fr/api.php?cp=".$_POST['cp'];
$var = file_get_contents($api);
preg_match("#<p id='(.*)'#", $var, $matches);
id = $matches[1];
echo $id;
}
im using this php code (from a question on here):
<?php
define(TEMPLATES_LOCATION, 'templates/');
function TemplateFunction ($template, $replaces) {
$template = file_get_contents(TEMPLATES_LOCATION . $template);
if (is_array($replaces)) {
foreach($replaces as $replacekey => $replacevalue){
$template = str_replace('{$' . $replacekey . '}', $replacevalue, $template);
}
}
return $template;
}
$keys = array(
'TITLE' => 'This is page title',
'HEADER' => 'This is some header',
'GALLERY' => 'php while loop here'
);
echo TemplateFunction('body.tpl', $keys);
?>
The way my template file is set up is the following HTML:
<body>
<div id="gallery">{GALLERY}</div>
</body>
so where {GALLERY} is, the php script should replace that with my automatically generated <li><img src="images/'.$filename.'"/></li> which is being run in a while loop generated from a mysql request
what i thought might work is:
$keys = array(
'TITLE' => 'This is page title',
'HEADER' => 'This is some header',
'GALLERY' => 'while($row = mysql_fetch_array($result)){<li><img src="'.$row['filename'].'"/></li>})'
);
but it doesnt :(
Re your code:
$keys = array(
'TITLE' => 'This is page title',
'HEADER' => 'This is some header',
'GALLERY' => 'while($row = mysql_fetch_array($result)){<li><img src="'.$row['filename'].'"/></li>})'
);
I would consider it very poor practice to have PHP code embedded in your template data this way. Allow me to offer you a completely different solution...
Firstly, we need to encapsulate the code. The code you've shown above is trying to fetch data from a $result variable, but $result itself is obviously been set elsewhere. This isn't good, because if we ever want to change the way the gallery feature works, we would need to search all over the code to find different bits of it.
Instead, you should write the feature as a self-contained function (or a class if it's too complex for a single function), which would load the data, and process it.
Let's call that function loadGallery(). It might look something like this:
function loadGallery() {
$output = '';
$result = mysql_query('...gallery query here...');
while($row = mysql_fetch_array($result)) {
$output .= "<li><img src='{$row['filename']}'/></li>";
}
return '<ul>'.$output.'</ul>';
}
Obviously, it could be a lot more complex than that (eg you may want to paginate it, or offer category options; these would be written as parameters for the function). I've also not written any error checking, etc here for brevity.
Now that you've got that function, you can plug it into the template engine. You need to reference the function in your template.
You currently have template markers like this {TITLE}. In your code, these markers are swapped with plain text using str_replace(). That's fine. But in this case we now want to call a function instead, so we need to have a different kind of marker.
Let's write the gallery marker like this: {FUNCTION:loadGallery} instead of {GALLERY} as you currently have.
Now you can have an additional bit of code in your template engine that looks at these {function:} markers and replaces them with a function call. (You can keep the existing simple str_replace() method as well of course)
$funcReplaces = array( //similar to your existing $keys array, but for allowed functions
'loadGallery'
);
foreach($funcReplaces as $replaceFunc){
$template = str_replace('{function:' . $replaceFunc . '}', $replaceFunc(), $template);
}
This will run the function and put the output into the template.
So that answers the question for you.
What I should point out, however, is that there are a lot of other issues that you need to think about when writing a templating engine, from both a technical and security perspective. The above describes a basic way to resolve the specific question at hand, but it isn't a fantastic all-singing all-dancing template engine. It's still just a pretty basic one.
That's fine, if that's all you need, but if you expect this system to grow, it's worth noting that this whole area is that this is very much a problem that others have already solved, and solved well. There are several very good templating engines available for PHP. I would suggest that your best course of action would be to investigate some of them, and maybe use one of those instead of writing your own.
Some that you could try:
Smarty
Twig
Mustache
Hope that helps.
You cannot "execute PHP code within an array". You simply build the array programmatically:
while (/* something */) {
$keys['GALLERY'][] = $something;
}
I have found the following code that i've written to be the right solution to my issue:
$gallery = array();
while($row = mysql_fetch_assoc($result))
{
$gallery[] = '<li><img src="'.$row['gallery_image_filename'].'" width="'.$final_image_width.'" height="auto" style="margin: '.$other_margin.'px '.$gallery_image_margin.'px '.$other_margin.'px 0px"/></li>';
}
$gallery = implode(' ', $gallery);
i then can concatenate my $gallery variable into the 'GALLERY' => 'value' value and it outputs all the database results as required. Thanks to all for your help :)
Well, you can create an class with __toString magic method which will process all images on your gallery and then return the string.
class TemplateGallery{
private $images = array();
public function addImage($src){
$images[] = $src;
}
public function __toString(){
$str = "";
foreach($images as $image){
$str .= sprintf('<li><img src="%s"></li>',$image);
}
return $str;
}
}
Well, as the guy in comments said, it's too "hard", so, you can use an "pre-process" function, that will process your images array, and then return your template string.
$images = array(/* Put images src here */);
function processGallery($images){
$str = "";
foreach($images as $image){
$str .= sprintf('<li><img src="%s"></li>',$image);
}
return $str;
}
And then call that function on your array.
I have something like this in one field of my table(MySql):
$data = '<td>apple</td>';
echo $data;
I select this field and echo it into the page.I want to replace 'apple' word with a php function that return a word.So I thought
$data = '<td>myphp_function('fruit');</td>';
echo $data;
but what I see in the page is exactly the line above and not my function output.
how can I do it?
I am not sure if i could explain my mean clearly...
Edited.
According to your last edit, what you need is the following:
$data = '<td>' . myphp_function('fruit') . '</td>';
echo $data;
This is assuming your myphp_function() will return some kind of value.
If the function echoes the value, it will not work as expected!
You can only execute PHP when you open PHP tags. Other than that, it's just plain text/html.
<td>myphp_function('fruit');</td>
To execute your function you have to open PHP tags:
<td><?php myphp_function('fruit'); ?></td>
you have to insert some sort of placeholder into your text. Like this
<td>[fruit]</td>
and then do a replace before printing it out:
$fruit = 'apple';
$text = str_replace('[fruit]',$fruit,$text);
Of course, for the real life usage there will be more complex solution.
So, you will do yourself enormous favor, if you post here your real task with real data example, not oversimplified and useless abstract question.
Let's say I have some code like this
if(isset($_GET['foo']))
//do something
if(isset($_GET['bar']))
//do something else
If a user is at example.com/?foo=abc and clicks on a link to set bar=xyz, I want to easily take them to example.com/?foo=abc&bar=xyz, rather than example.com/?bar=xyz.
I can think of a few very messy ways to do this, but I'm sure there's something cleaner that I don't know about and haven't been able to track down via Google.
Here's one way....
//get passed params
//(you might do some sanitizing at this point)
$params=$_GET;
//morph the params with new values
$params['bar']='xyz';
//build new query string
$query='';
$sep='?';
foreach($params as $name=>$value)
{
$query.=$sep.$name.'='.urlencode($value);
$sep='&';
}
If you are updating the query string you need ot make sure you don't do something like
$qs="a=1&b=2";
$href="$qs&b=4";
$href contains "a=1&b=2&b=4"
What you really want to do is overwrite the current key if you need to .
You can use a function like this. (disclaimer: Off the top of my head, maybe slightly bugged)
function getUpdateQS($key,$value)
{
foreach ($_GET as $k => $v)
{
if ($k != $key)
{
$qs .= "$k=".urlencode($v)."&"
}
else
{
$qs .= "$key=".urlencode($value)."&";
}
}
return $qs
}
View report
Just set the link that changes bar to xyz to also have foo=abc if foo is already set.
$link = ($_GET['foo'] == 'abc') ? 'foo=abc&bar=xyz' : 'bar=xyz';
?>
Click Me
You would have to render out the links with the proper URL querystring to make that happen. This is a design decision that you would need to make on your end depending on how your system is setup.
I have some sites that have this issue, and what I do is setup a querystring global variable that sets the current page data the top of the page request.
Then when I am rendering the page, if I need to make use of the current query string I do something like:
echo '<a href="myurl.php' . querystring . '&bar=foo';
It's not the cleanest, but it all depends on how your system works.
Save some code and use the built-in http_build_query. I use this wrapper in one of my projects:
function to_query_string($array) {
if(is_scalar($array)) $query = trim($array, '? \t\n\r\0\x0B'); // I could split on "&" and "=" do some urlencode-ing here
else $query = http_build_query($array);
return '?'.$query;
}
Also, though it isn't often used, you can have $_GET on the left-hand side of an assignment:
$_GET['overriden_or_new'] = 'new_value';
echo 'Yeah!';
Other than that, just do what Paul Dixon said.