cereal 1,524 Nearly a Senior Poster Featured Poster

Hi,

you have to perform a select query inside the methods isUserExistscustomer() and $this->isUserExistsmobile() and return boolean TRUE or FALSE.

For example:

public function isUserExistsmobile($mobile_no)
{
    $stmt = $this->conn->prepare("SELECT id FROM np_system_users WHERE customer_mobileno = ?");
    $stmt->bind_param('s', $mobile_no);
    $stmt->execute();
    $stmt->store_result();

    return $stmt->num_rows > 0 ? TRUE : FALSE;
}

Do the same for the email. The mobile number should be trimmed, to avoid leading and trailing spaces that could trick the system and allow duplicates:

$mobile_no = trim($mobile_no);

You should also remove spaces, dashes, dots inside the string, i.e. convert 555-123 231 to 555123231 and you should match prefixes which can be expressed in two ways, for example the international prefix for USA is 001 which can be shorted to +1.

So here you should decide if the client can insert prefixes manually or by a dropdown menu (select tag), and if you want to reject the input which is not composed just by digits.

Regarding the trim() function the same applies to email addresses, where you should lower the case to avoid values like abc@some.tld and Abc@some.tld. You can use mb_strtolower() or the MySQL function LOWER(), however this depends also on the charset assigned to the table column:

cereal 1,524 Nearly a Senior Poster Featured Poster

Hi,

since you set $Filter on line 5 the condition on line 7 will never verify, so you could remove it. What you should do is to verify if the GET attribute is set and valid, do:

$url = filter_input(INPUT_GET, 'url', FILTER_VALIDATE_URL);

Then replace the IF condition at line 7 with:

if($url !== FALSE)

Docs:

cereal 1,524 Nearly a Senior Poster Featured Poster

Add a javascript event listener, when the form changes submit the query through an AJAX request. To make it work correctly separate the query script so that it returns only the data you want to display in the page.

cereal 1,524 Nearly a Senior Poster Featured Poster

You're looping the $_POST array, instead you have to loop the $_FILES array. Follow the documentation and the comments at this page:

If still in doubt create a dummy upload script and place this:

<?php

    echo "<p>$_POST array:</p>";
    echo "<pre>" . print_r($_POST) . "</pre>";

    echo "<p>$_FILES array:</p>";
    echo "<pre>" . print_r($_FILES) . "</pre>";

so you can see what is generated by your upload form.

cereal 1,524 Nearly a Senior Poster Featured Poster

Uh, sorry, due to chosen forum and title I thought it was related to the framework, not to the CSS rules.

It happens probably because of this rule:

.register form input {
    width: 95%;
    height: 30px;
    background: #fcfcfc;
    border: 1px solid #ddd;
    -moz-border-radius: 2px;
    -webkit-border-radius: 2px;
    border-radius: 2px;
    -moz-box-shadow: 0 1px 3px 0 rgba(0,0,0,.1) inset;
    -webkit-box-shadow: 0 1px 3px 0 rgba(0,0,0,.1) inset;
    box-shadow: 0 1px 3px 0 rgba(0,0,0,.1) inset;
    font-family: 'PT Sans', Helvetica, Arial, sans-serif;
    color: #888;
    font-size: 16px;
}

use input[type=text] to match only text inputs and occasionally add types like password, number, email. Otherwise use not(), for example to avoid only radio buttons do:

input:not([type=radio])

To include also checkboxes assign a class to these input fields and then use not on the class, for example:

<input type="radio" name="abc" value="1" class="input_check_radio">
<input type="radio" name="abc" value="2" class="input_check_radio">

<input type="checkbox" name="def" value="alpha" class="input_check_radio">

And for the rule:

input:not(.input_check_radio)

Live example: http://jsfiddle.net/ptu3wv3s/

cereal 1,524 Nearly a Senior Poster Featured Poster

Hi,

which version are you using? With version 3 you can use set_checkbox() instead of set_value(). In this case write something like:

<label for="sex_1">
    <?php echo form_radio('sex', 1, set_checkbox('sex', 1), "id='sex_1'"); ?> male
</label>

<label for="sex_2">
    <?php echo form_radio('sex', 2, set_checkbox('sex', 2), "id='sex_2'"); ?> female
</label>

Docs: http://www.codeigniter.com/user_guide/helpers/form_helper.html#set_checkbox

cereal 1,524 Nearly a Senior Poster Featured Poster

Ok, you have to fix two things here:

A) add publish_pages to the scope:

$permissions = ['publish_actions', 'manage_pages', 'email', 'publish_pages'];

B) the third argument for $fb->post() must be the page access token, not the user access token which is set previously. So:

$pageTokens = $fb->get('/me/accounts?fields=id,name,access_token')
                 ->getGraphEdge()
                 ->asArray();

foreach($pageTokens as $key => $value)
{
    # match page ID
    if($value['id'] == 357971644373038)
    {
        $pageToken = $value['access_token'];
        break;
    }

}

$response = $fb->post('/357971644373038/feed', $linkData, $pageToken);

The page access token expires after one hour. With these changes you should be able to write to a page.

cereal 1,524 Nearly a Senior Poster Featured Poster

You have to add the appropriate permission in order to post to the timeline, this is done by appending the scope parameter to the login link, in your case the value to use should be publish_actions, but check the documentation to apply the correct permissions:

Read it carefully, especially the reference / public_actions section at the end of the document.

cereal 1,524 Nearly a Senior Poster Featured Poster

Could you paste the full stylesheet?

cereal 1,524 Nearly a Senior Poster Featured Poster

Are you sure you're not missing some closing parentheses in the first block? I don't see how both rules could apply when the second range is not reached by your resolution.

By the way, is this portrait oriented?

cereal 1,524 Nearly a Senior Poster Featured Poster

Ok, the URI registered in your script and in your App defines the port number:

http://localhost:80/feedreader/fdposter.php

But in your browser (screenshot) the port number is missing:

http://localhost/feedreader/fdposter.php

If you're using port 80, then try to remove it from the App settings and from the script, as this is an implicit port number and could generate this kind of problems.

In other words, set the redirect URI in App settings and in your script to:

http://localhost/feedreader/fdposter.php
cereal 1,524 Nearly a Senior Poster Featured Poster
cereal 1,524 Nearly a Senior Poster Featured Poster

The error message suggests to enable the web OAuth login, so go to your Facebook App dashboard > Settings > Advanced, scroll to Client OAuth Settings and set Web OAuth Login to Yes, then it should work.

cereal 1,524 Nearly a Senior Poster Featured Poster

Ok, what's your current code?

Consider that you should change the code block that returns the results by removing the echo and the die constructs and by replacing them with return:

if(($result = $this->sendMail($to, $subject, $body, $headers)) === TRUE)
    return json_encode(['success' => true]);

else
    return json_encode(['error' => $result]);

Consider that the die construct stops also the execution of the calling script, so when you include your mailer class into another file it will not return all the expected output, which is not good for production. This construct should be used when you have to debug code.

By the way, if you don't want to show error details then you can also change the IF statement to something simplier:

if($this->sendMail($to, $subject, $body, $headers))
    return json_encode(['success' => true]);

else
    return json_encode(['error' => 'something really wrong just happened']);

And switch back to a boolean return in sendMail():

return $mail->Send();
cereal 1,524 Nearly a Senior Poster Featured Poster

Do I need to configure something in xampp when I'm still using PHPMailer

No, the error seems related to the SMTP server.

As long SMTP server, port number and credentials are correct then you should be able to send the message, at the moment it seems that the connection attempt timeouts, is the SMTP server url correct?

Make sure these values are correct, especially Host and Port:

$mail->Host = 'stmp.emailsrvr.com';
$mail->Username = 'gideon.a@scopicsoftware.com';
$mail->Password = '*******';
$mail->Mailer = 'stmp';
$mail->Port = 25;
$mail->SMTPAuth = true;
cereal 1,524 Nearly a Senior Poster Featured Poster

Sorry, I forgot to set the boolean check in:

if($result = $this->sendMail($to, $subject, $body, $headers)) {

Change it to:

if(($result = $this->sendMail($to, $subject, $body, $headers)) === TRUE) {

And it will show the success message only when sendMail() explicitly returns boolean TRUE.

In reference to the error message switch the debug level to 3 to get more information. But I think it's due to the $headers argument, you are setting setFrom() with the sender email address.

Instead use the email that authenticates within the SMTP server, you are not authenticating the sender so you cannot use it in the FROM header. Set the sender email address in AddReplyTo(), so:

$mail->setFrom('gideon.a@scopicsoftware.com');
$mail->AddReplyTo($headers);
cereal 1,524 Nearly a Senior Poster Featured Poster

Hi!

Add to the sendMail() method:

$mail->SMTPDebug = 2; # switch to 3 or 4 to increase verbosity

Then change the return of the sendMail() method to:

if( ! $mail->Send())
    return $mail->ErrorInfo;

return TRUE;

And in actionSendMail() replace the previous sending mail code block with:

//Sending mail 
if($result = $this->sendMail($to, $subject, $body, $headers)) {
    $response = json_encode(['success' => true]);
    echo $response;
} else {
    $response = json_encode(['error' => $result]);
    die($response);
}

Now you should be able to read what is sent to the SMTP server and see why it fails.

cereal 1,524 Nearly a Senior Poster Featured Poster

Assuming that $path is relative to the CodeIgniter main index.php file, then change path to:

$path = FCPATH . 'uploads/path/';

The constant FCPATH is defined in the index.php file. Then simply loop the $files array against unlink():

array_map('unlink', $files);

And that's all.

cereal 1,524 Nearly a Senior Poster Featured Poster

Is this the code of the http://localhost:8000/feedreader/fbindex.php script?

The redirect url MUST be the script that will receive the authorization code appended to the link, for example:

http://localhost:8000/feedreader/fbindex.php?code=AUTHORIZATION_CODE

The value of $_GET['code'] is read by:

$session = $helper->getSessionFromRedirect();

Which enables the Facebook Session by realesing an access token that you must save in some way, for example into a PHP session, otherwise, and this is important, when you browse to another page you will loose it.

In your current code it seems you are trying to save the access token before clicking the access link. Which is hidden because there is no Facebook session at the moment. So try:

if(isset($session))
{
    $_SESSION["access_token"]=$session->getToken();
}

else
{
    echo "<a href='".$helper->getLoginUrl()."'>Login with Facebook</a>";
}

And it should work.

cereal 1,524 Nearly a Senior Poster Featured Poster

By using $session->getToken() you get the access token. For example when you perform the login request you use a script like this:

<?php

session_start();

require_once "credentials.php";
require_once "autoload.php";
use Facebook\FacebookSession;
use Facebook\FacebookRequest;
use Facebook\GraphUser;
use Facebook\FacebookRequestException;
use Facebook\FacebookRedirectLoginHelper;

$redirect_url = "http://localhost:8005/logged.php";

$helper = new FacebookRedirectLoginHelper($redirect_url, $appId, $appSecret);
echo '<a href="' . $helper->getLoginUrl() . '">Login with Facebook</a>';

The logged.php file in the redirect url is this:

<?php

error_reporting(-1);
session_start();

require_once "credentials.php";
require_once "autoload.php";
use Facebook\FacebookSession;
use Facebook\FacebookRequest;
use Facebook\GraphUser;
use Facebook\FacebookRequestException;
use Facebook\FacebookRedirectLoginHelper;

$redirect_url = "http://localhost:8005/logged.php";

FacebookSession::setDefaultApplication($appId, $appSecret);
$helper       = new FacebookRedirectLoginHelper($redirect_url);

try {

    $session = $helper->getSessionFromRedirect();

    if(isset($session))
    {
        # save token to PHP session
        $_SESSION['access_token'] = $session->getToken();

        # show some text
        echo "<p><a href=\"get.php\">Perform a GET request</a></p>";
    }
}

catch(FacebookRequestException $e) {
    echo "Exception occured, code: " . $e->getCode();
    echo " with message: " . $e->getMessage();
}

catch(\Exception $e) {
    echo "Exception occured, code: " . $e->getCode();
    echo " with message: " . $e->getMessage();
}

Which is where you are redirected by Facebook. Then you browse to another page (in the example this is get.php) where you read the token from the PHP session and perform a request against Facebook:

<?php

error_reporting(-1);
session_start();

require_once "credentials.php";
require_once "autoload.php";
use Facebook\FacebookSession;
use Facebook\FacebookRequest;
use Facebook\GraphUser;
use Facebook\GraphObject;
use Facebook\GraphSessionInfo;
use Facebook\FacebookRequestException;

FacebookSession::setDefaultApplication($appId, $appSecret);

# Get the token from PHP session:
$session = new FacebookSession($_SESSION['access_token']);

$user_profile = (new FacebookRequest($session, 'GET', '/me'))
                ->execute()
                ->getGraphObject(GraphUser::className());

echo "Name: " . $user_profile->getName();

Note: by using the autoload.php file released in …

cereal 1,524 Nearly a Senior Poster Featured Poster

Also, have you checked if the file is loading through the browser console? On Google Chrome press CTRL + SHIFT + J then go to the Network tab and reload the page, check if the css file loads with 2xx or 3xx status codes.

cereal 1,524 Nearly a Senior Poster Featured Poster

Try to add the (root) slash to the link:

<link
    rel="stylesheet"
    type="text/css"
    href="/resources/css/docTech25Banner.css" />

Otherwise the link will be relative to the current path, if you are in /contact/, for example, the browser will expect to find the css file inside:

/contact/resources/css/docTech25Banner.css

And so on for each browsed path of the website.

cereal 1,524 Nearly a Senior Poster Featured Poster

Great, you're welcome. If we have finished, then please mark the article as solved. Bye!

cereal 1,524 Nearly a Senior Poster Featured Poster

You're welcome!

This $_POST['query + website']; cannot work, because there you're trying to access an index key, in order to work your array should look have an index key like in your test:

$a = array(
        'query'           => 'abc',
        'website'         => 'http://some.url/',
        'query + website' => 'def'
    );

echo $a['query'];
echo $a['website'];
echo $a['query + website'];

You can use string concatenation:

$message  = $_POST['query'] . "\n\r";
$message .= "Website: " . $_POST['website'] . "\n\r";

$this->Body = $message;

by prepending the assignment operator (=) with a dot (.) you append the new value to the variable instead of overwriting it. Which is the same of writing:

$message = $_POST['query'] . "\n\r Website: " . $_POST['website'] . "\n\r";

Note: double quotes are important to properly translate the linefeed (\n) and carriage return (\r) characters.

cereal 1,524 Nearly a Senior Poster Featured Poster

Just replace the text with the input received from the form:

$message = $_POST['query']; # name of textarea

And then set the body:

$mail->Body = $message;

The same applies to subject and altbody (which is optional and helpful if in body you set an HTML message). To get the email address of the sender replace:

$mail->addAddress('office@---.com');

With:

$email = $_POST['email'];

$mail->addAddress($email);

For the moment get it to work, after that you MUST add validation and sanitazation, because at the moment the script is not safe against attacks. The validation & sanitazation process is not complex you just have to add some rules through filter_input(), as example:

$name    = filter_input(INPUT_POST, 'name', FILTER_SANITIZE_STRING);

# sanitize
$email   = filter_input(INPUT_POST, 'email', FILTER_SANITIZE_EMAIL);

# validate if sanitization was successful
$email   = filter_input(INPUT_POST, 'email', FILTER_VALIDATE_EMAIL);

$message = filter_input(INPUT_POST, 'query', FILTER_SANITIZE_STRING);

Docs:

A sanitize filter is used to remove extra characters, like javascript, html tags, null bytes. A validation filter, instead, is used to verify that the input is in the correct format. When filter_input() fails it returns boolean FALSE, so after you set the variables $name, $email and $message you could verify the status of them and decide if run the mail script or not, so you should just replace:

if(!$mail->send()) {

with:

if($name !== FALSE && $email !== FALSE && $message !== FALSE && !$mail->send())

Or, better, you could place an independent if statement before …

cereal 1,524 Nearly a Senior Poster Featured Poster

It could be the port or the password. Remove the comment character from line 12 to enable the debugger and access the information, with level 3 it will show the communications between server and client:

$mail->SMTPDebug = 3;

And also follow the link returned by the error:

It explains why the connection can fail.

cereal 1,524 Nearly a Senior Poster Featured Poster

There is a condition under which $_POST and $_FILES are not populated, it's related to the value of enable_post_data_reading, if this is 0 then it's disabled. Are you including some php script that uses ini_set()?

cereal 1,524 Nearly a Senior Poster Featured Poster

You can use the same form, which by the way seems fine, even when the file uploads are disabled you should still receive the POST body request from the form. Can you show the receiving script?

Some docs that could be useful:

cereal 1,524 Nearly a Senior Poster Featured Poster

In addition: you could add a timeout to file() so that if the resource is not reachable, it will stop after a defined number of seconds and emit an E_WARNING message:

$options["http"]  = array(
    "method"    => "GET",
    "header"    => "Content-Type: text/xml; charset=UTF-8\r\n".
                   "Connection: close\r\n",
    "timeout"   => 15,
);
$context = stream_context_create($options);

if( ! ($fp = fopen($file, "r", FALSE, $context))) {
cereal 1,524 Nearly a Senior Poster Featured Poster

Hi!

Which is the error? The thread title is truncated. And, can you share your code and explain where the issue happens?

I suppose you're using their library, is this correct?

cereal 1,524 Nearly a Senior Poster Featured Poster

Heh, I just came to the same solution, correct link is:

The problem happens because the old link asks for a session cookie, which is not submitted by the request, in absence it will return an HTML page, instead of the XML. You can test it by using file_get_contents():

$file = "http://www.sciencedaily.com/rss/space_time/space_exploration.xml";
print_r(file_get_contents($file));

Besides: at line 73 you're declaring $numItems; without any default value, which means the variable is still undefined, and it will fail if for example you do something like:

$a;
echo $a++;

Bye!

cereal 1,524 Nearly a Senior Poster Featured Poster

It is the Space Exploration feed from Science Daily:

No, I was asking for your RSS feed not for the source but yes, at this point, as suggested by pixelsoul share also your PHP code.

cereal 1,524 Nearly a Senior Poster Featured Poster

Yes, just replace * with the path, for example:

rm -rdf /tmp/something/

I suggest you to read the manual, it explains all the available options and there are also few examples.

cereal 1,524 Nearly a Senior Poster Featured Poster

Does this information indicate the problem is with the PHP code, or the incoming feed?

It seems related to the XML document, not to PHP, otherwise the error would be at PHP level. Could you share the XML?

cereal 1,524 Nearly a Senior Poster Featured Poster

Hi,

you can use rm -rdf * it will remove all files and directories recursively. For more information about the options read the manual: man rm and be careful, always check current path, as it can hurt.

cereal 1,524 Nearly a Senior Poster Featured Poster

Hi, you could loop the $invoice->addItem() method, but this is part of a class I don't have access to, and I don't know how this works (could you share more about it?).

Anyway, try to check the documentation of the $invoice class, to see if it handles arrays of if there's a method like addItems().

cereal 1,524 Nearly a Senior Poster Featured Poster
cereal 1,524 Nearly a Senior Poster Featured Poster

Oh, you can create a separated script and included it, just place it on top of the file and check if the request method is POST, and if the submission comes from the contact form, for example:

<?php

    $result = FALSE;

    if($_POST && array_key_exists('action', $_POST))
    {
        # mail script here
        $result = require './send.php';
    }
?>
<!DOCTYPE html>
<html>
    ...

<?php if($result) echo "<p>{$result}</p>"; ?>

And at the end of the send.php script, instead of:

echo ! $mail->send() ? 'Error: ' . $mail->ErrorInfo : 'Success!';

You place a return:

return ! $mail->send() ? 'Error: ' . $mail->ErrorInfo : 'Success!';

Now the $result variable will carry the value returned by the included script.

Otherwise point the form directly to the script and then redirect back with a session message. It's up to you.

cereal 1,524 Nearly a Senior Poster Featured Poster

Sorry, I'm not sure I've understood: you mean how to connect the form to the sending script? Through the action attribute of the form tag:

<form action="contact_page.php" method="POST">

Besides, the enctype should defined only when it's expected to upload a file through the form, yours does not seem to be the case, so you can remove it.

cereal 1,524 Nearly a Senior Poster Featured Poster

You're welcome.

where do i find the smtp password ?

It's the password that you use to access the defined email account.

As I wrote: in a script like this, sender (FROM) and receiver (TO) can be the same email address. But:

  1. this requires the disclosure of the password of this email account;
  2. if this password is changed the script will fail.

For this reason I suggest to dedicate an email account only to the scripts. From your hosting control panel you should be able to create a new email account and to define his password.

cereal 1,524 Nearly a Senior Poster Featured Poster

Let me try to explain: when you send an email message from your email client (for example Outlook or Mozilla Thunderbird) you connect to an SMTP server, submit password and if it's ok it will allow the sending of the message. You create the connection to SMTP and POP3 servers during the setup of the account, correct?

Now: when you send an email message from a PHP script you need to execute the same steps, otherwise, the SMTP server will deny the access and the email message will not be delivered.

At the moment at line 29 you are defining the FROM header basing on the sender email address:

$from="From: $name<$email>\r\nReturn-path: $email"; 

This is wrong, because this is the email defined by the client through your contact form. You don't have access to his credentials, so you cannot set the FROM header with his email address.

What you have to do is to:

  1. define, in your script, an email address that you can authenticate through a password, for example: web@website.com which will be used in the FROM header;
  2. use the Reply-To header to define the client email address, i.e. the value of the $email variable.

How to accomplish this? Use a PHP library that allows you to connect to your SMTP server. Something like PHPMailer:

An example:

<?php

require './PHPMailerAutoload.php';

$name    = $_REQUEST['name']; 
$email   = $_REQUEST['email']; 
$message = $_REQUEST['message']; 

$mail = new PHPMailer;
$mail->isSMTP();
$mail->SMTPDebug = 2;

# authentication
$mail->SMTPAuth  = TRUE;
$mail->Host      = …
cereal 1,524 Nearly a Senior Poster Featured Poster

Hi,

when the query fails MySQLi will return FALSE, so add mysqli_error() to get some information about it.

I think there is an ambiguous column error, which means the two tables have at least a column with the same name, for example postdate.

cereal 1,524 Nearly a Senior Poster Featured Poster

Hi,

it seems the same issue you had last month:

The sender email must be authenticated before sending the email. The email to authenticate is the one set in the FROM header, i.e. the one defined here:

$headers = "From: website@website.com" . "\r\n";

Free hostings solves this problem by replacing the FROM email address with their and by setting yours as REPLY_TO, so they don't have to authenticate your SMTP server. For this reason it appears to work fine. Check the headers of the test messages you have sent.

cereal 1,524 Nearly a Senior Poster Featured Poster

You could use xpath() to match only the selected questions:

$xpath = $xml->xpath('//main[@select="selected"]');

So you can remove the IF statement:

if($main['select'] == "selected")

Then count to get the total and create a simple pagination system:

$count = count($xpath);
$page  = isset($_GET['page']) && $_GET['page'] > 0 ? $_GET['page'] : 1;
$numbr = $page - 1;

# load the current question
$main  = $xpath[$numbr];

Once you have $main, you don't need this loop:

foreach($xml->main as $main)

Then create the page links:

<ul class="nav">
    <?php
    for($i = 1; $i <= $count; $i++)
    {
        if($page == $i)
            echo "<li><a class=\"current\" href=\"question.php?page={$i}\">{$i}</a></li>";

        else
            echo "<li><a href=\"question.php?page={$i}\">{$i}</a></li>";
    }
    ?>
</ul>

And to your form code simply add the question id, which is the attribute id in the main object:

<input type="hidden" name="questionID" value="<?php echo $main->attributes()->id; ?>" />

Docs:

cereal 1,524 Nearly a Senior Poster Featured Poster

Hi,

you could count the nodes, create a range array and then shuffle the range, finally you return the node, for example:

<?php 

    $xml = <<<EOD
<?xml version="1.0" encoding="UTF-8"?>
<main>
    <articles>
        <article>
            <title>Title 001</title>
            <content>Content 001</content>
        </article>
        <article>
            <title>Title 002</title>
            <content>Content 002</content>
        </article>
        <article>
            <title>Title 003</title>
            <content>Content 003</content>
        </article>
    </articles>
</main>
EOD;

    $load  = simplexml_load_string($xml);
    $count = $load->articles->article->count();

    if($count > 0)
    {
        $numbr = $count > 2 ? $count - 1 : $count;
        $range = range(0, $numbr);

        shuffle($range);

        echo $load->articles->article[$range[0]]->title . PHP_EOL;
    }

    else
    {
        echo "No articles found!";
    }

If you have doubts, please show your XML structure, otherwise it's difficult to help. Bye!

cereal 1,524 Nearly a Senior Poster Featured Poster

Same for me, I just received a notification sent 4 days ago.

cereal 1,524 Nearly a Senior Poster Featured Poster

Hi,

remove the WHERE condition and add GROUP BY student_code to the select statement and it should work fine, but consider that you could use a view, otherwise when you add something else to the results table you have to check and update the totals table.

Examples:

INSERT INTO `results`(`student_code`, `mark`) VALUES(1, '10.20'), (1, '5.30'), (2, '7.30'), (3, '1.25'), (2, '1.25'), (3, '100.99');

INSERT INTO `totals`(`student_code`, `total`) SELECT `student_code`, SUM(`mark`) AS total FROM `results` GROUP BY `results`.`student_code`;

Or:

CREATE VIEW `v_totals` AS SELECT `student_code`, SUM(`mark`) AS `total` FROM `results` GROUP BY `student_code`;

Live examples: http://sqlfiddle.com/#!9/552f4/1

cereal 1,524 Nearly a Senior Poster Featured Poster

A prepared statement consists in a group of SQL commands submitted by the MySQL client:

These are supported by both PDO and MYSQLi. When you see the -> it means you're accessing an object, but the same can be done with the procedural style.

Almost always the PHP documentation offers the examples for both styles, check this example:

<?php
$link = mysqli_connect("localhost", "my_user", "my_password", "world");

/* check connection */
if (mysqli_connect_errno()) {
    printf("Connect failed: %s\n", mysqli_connect_error());
    exit();
}

$city = "Amersfoort";

/* create a prepared statement */
$stmt = mysqli_stmt_init($link);
if (mysqli_stmt_prepare($stmt, 'SELECT District FROM City WHERE Name=?')) {

    /* bind parameters for markers */
    mysqli_stmt_bind_param($stmt, "s", $city);

    /* execute query */
    mysqli_stmt_execute($stmt);

    /* bind result variables */
    mysqli_stmt_bind_result($stmt, $district);

    /* fetch value */
    mysqli_stmt_fetch($stmt);

    printf("%s is in district %s\n", $city, $district);

    /* close statement */
    mysqli_stmt_close($stmt);
}

/* close connection */
mysqli_close($link);

?>

Source: http://php.net/manual/en/mysqli-stmt.prepare.php#example-1887

cereal 1,524 Nearly a Senior Poster Featured Poster

@phoenix

that's why I was writing about prepared statements, the quote is not supposed to be submitted to the query, unless is escaped correctly, and that's why the security test was generating the syntax error, they supposed you where using quotes in your query:

"SELECT * FROM items WHERE ITEM = '$ITEM'"

So they tried to escape them by submitting the number with a quote:

71'

To get a query like this:

"SELECT * FROM items WHERE ITEM = '71''"

Which seems to not make sense but if you add other instructions right after the quote, you could execute whatever you want:

71' OR '1'='1

for example. At the end the query will look like this:

"SELECT * FROM items WHERE ITEM = '71' OR '1'='1'"

To solve with MySQLi you can use prepared statements or you can escape the input with mysqli_real_escape_string():

$id = mysqli_real_escape_string($con, $id);
$item_query = mysqli_query($con ,"SELECT * FROM product WHERE item_id = $id ");

Docs:

cereal 1,524 Nearly a Senior Poster Featured Poster

Hi all!

@phoenix

I suppose you have a form with an input field like this:

<input type="text" name="ITEM" id="ITEM">

From which you set the $ITEM variable, so try to send something different from the expected value, you expect an integer. Send this instead:

1 OR 1=1

It will probably return all the rows in the item table. This is an SQL injection and it means the input submitted to the query function is not sanitized nor validated, so an attacker can try to run other queries and get some extra information or execute remote code.

This is the reason you should use prepared statements, for example:

$stmt = $mysqli->prepare("SELECT * FROM item WHERE id = ?");
$stmt->bind_param('i', $ITEM);
$stmt->execute();

$results = $stmt->get_result();

# looping results
while($row = $results->fetch_assoc())

For more examples check this code snippet by pritaeas: