1

From the documentation:

If called from within a function, the return statement immediately ends execution of the current function, and returns its argument as the value of the function call.

It is like doing:

echo 'hello';
exit;
echo 'world';

so in your function you can store the value that you want to return into a variable, you can use the assignment operator .= and then return the variable at the end of the function execution:

function generate_list($rows)
{
    # initialize the $str variable
     $str = "
     <table>
     <tr>
         <th>Firstname</th>
        <th>Sirname</th>
        <th>Email</th>
        <th>Phonenumber</th>
        <th>Information</th>
     </tr>";

     while($row = $rows->fetch_assoc())
     {
         # append values to the $str variable
         $str .= "
         <tr>
            <td>{$row['Firstname']}</td>
            <td>{$row['Sirname']}</td>
            <td>{$row['Email']}</td>
            <td>{$row['Phonenumber']}</td>
            <td>{$row['Information']}</td>
        </tr>";
     }

     # append values to the $str variable
     $str .= "</table>";

     # finally return the contents of $str
     return $str;
}

$results = $con->query("SELECT * FROM listing");

# store the results of the function into $list
$list = generate_list($results);

# print the contents of $list when needed
echo $list;

$results->free();
$con->close();

About the connection to the database, you could set that outside of the function scope, what happens if you have 30 functions pulling results from the database and you have to change the credentials?

2

@UI

Hi!

in addition to previous comments, if you are learning PHP for work, sooner or later you will handle legacy code, you will be asked to add functionalities, not always to port it. You cannot always choose the version to work with. For example, something simple like:

$i = 1024**2*10;

returns a syntax error if you use PHP <= 5.5 and works fine when using the latest versions. To avoid issues in such case, you would write:

$i = 1024*1024*10;

Or see how list() changed the behaviour between PHP 5 and 7 when using array indices, that's just insane (it was from the beginning). IMHO, you need to know these things too, to become more efficient.

2

Hmm, the session in this case it is not, probably, the best approach: what happens if, in the current session, you open multiple tabs of A.php with different IDs?

A.php?id=123
A.php?id=124
A.php?id=125
...

It would screw up, because the session value would be rewritten by the latest loaded tab. Append the query string to B.php, so if you are using a form you can do:

<form method="get" action="B.php?id=123">

Or hide it in the input fields:

<input type="hidden" name="id" value="123">

If you want more appropriated help, share an example of what you are trying to do.

Votes + Comments
Good shout about multiple tabs +1 - a common gotcha!
2

Right now, change line 13 to:

if(mysqli_num_rows($query_run)>0)

There is also another error here:

$query_run = mysqli_query($query,$db);

The first argument of the function must be the link to the database, the second the query statement. So:

$query_run = mysqli_query($db, $query);

Regarding prepared statements you have to change the approach and use the MySQLi Prepared Statement class. You can find the documentation here:

So, define the query to perform:

$query = "SELECT * FROM `tbl_employee_information` WHERE `employeeno` = ? AND `name` = ?";

Instead of writing variables directly inside the query string, replace them with placeholders and bind the parameters through the bind_param() function.

MySQLi allows procedural and object oriented styles.

Procedural style:

$stmt = mysqli_prepare($db, $query);
mysqli_stmt_bind_param($stmt, 'is', $empNo, $name);
mysqli_stmt_execute($stmt);
mysqli_stmt_store_result($stmt);

if(0 < mysqli_stmt_num_rows($stmt))
{
    # code
}

mysqli_stmt_free_result($stmt);

The object oriented style looks like:

$stmt = $db->prepare($query);
$stmt->bind_param('is', $empNo, $name);
$stmt->execute();
$stmt->store_result();

if(0 < $stmt->num_rows)
{
    # code
}

$stmt->free_result();

The is stands for i integer, s string, for the $empNo and $name variables. You can find which types you can define, inside the bind_param() function documentation.

A word on $empNo and $name, you are currently using $_POST, use filter_input(), instead, as you can sanitize the input:

$empNo = filter_input(INPUT_POST, 'employeeno', FILTER_SANITIZE_NUMBER_INT);
$name = filter_input(INPUT_POST, 'employeeno', FILTER_SANITIZE_STRING);

The docs about the filters:

Bye!

Votes + Comments
Excellent, as usual.
1

Hi,

in this case the error message is very descriptive:

PHP Parse error: syntax error, unexpected '"', expecting '-' or identifier (T_STRING) or variable (T_VARIABLE) or number (T_NUM_STRING) in /home/sn/public_html/sn/home.php on line 168

It points to a specific file and line of the code. If you don't find the error in that line then search above. On line 133 of home.php there is a backtick:

exit();` // <-- remove this

If you want to learn PHP, learn to reproduce bugs: isolate the code that generates the error and try to get the same error message:

<?php

print 'hello';`
print 'world';

Generates:

PHP Parse error: syntax error, unexpected end of file, expecting '`' in /tmp/a.php on line 5

Also the backtick operator as a specific meaning in PHP as it's an alias of shell_exec(), you can run a command like this:

$arg  = array_key_exists(1, $argv) ? escapeshellarg($argv[1]) : '';
print `find . -type f -iname "$arg" 2> /dev/null`;

> php a.php *.jpg

More info: http://php.net/manual/en/language.operators.execution.php
The comment part of the manual, sometimes, is very useful.

1

Okay,

a part lines from 13 to 19, which are blanking the variables and I suppose it's just an error here in the paste, at line 21 (the $query) you have " or die(mysqli_error($conn)); at the end of the string, so when you run the query at line 22, it will fail, change this:

$query = "INSERT INTO meets (`event_type`,`event_date`,`event_country`,`event_postcode`,`event_title`,`event_description`,`event_ltm`) VALUES ('$event_type','$event_date','$event_country','$event_postcode','$event_title','$event_description','$event_ltm')" or die(mysqli_error($conn));

To:

$query = "INSERT INTO meets (`event_type`,`event_date`,`event_country`,`event_postcode`,`event_title`,`event_description`,`event_ltm`) VALUES ('$event_type','$event_date','$event_country','$event_postcode','$event_title','$event_description','$event_ltm')";

And try:

$result = mysqli_query($conn, $query);

if( ! $result)
    print sprintf('Error (%s) %s', mysqli_errno($conn), mysqli_error($conn));

You could also print the $query statement and try if it works fine through a MySQL client:

print $query;
1

If the query does not return a result set, then the loop will not assign any value to $_SESSION and the print statement will show the previous value associated with that index: $_SESSION['status'].

I take the above for an example, but if $muser and $mypass are not set then the query will return all rows in the table.

So, if multiple rows are returned by the query, then $_SESSION will be overwritten and show the values of the last loop.

Right after session_start() add:

print print_r($_SESSION, TRUE);

This should tell you if you are carrying the value set by a previous step. Do the same after the loop. And see what you get.

1

Localhost? It seems a ramsonware, a virus that encrypts data and ask money to return the files back. If you are using Windows that's probably in your system, so it should not be related to the application code. The same can happen if the folder is shared in a local network and the virus is compromising all the files it can reach.

Good luck with that.

1

This line will raise an error and kill the execution:

trigger_error('Wrong SQL: ' . $sql . ' Error: ' . $conn->error, E_USER_ERROR);

If you want to use it, then you have to create a condition, something like this:

if( ! $result)
    trigger_error('Wrong SQL: ' . $sql . ' Error: ' . $conn->error, E_USER_ERROR);

Otherwise it will run at each execution.

1

Hi,

the recommended way to hash passwords in PHP is through password_hash(), see the examples in the documentation page:

The example #3 seems similar to your request. If you will use PHP 7, then you can enable strict mode and you can write something like this:

<?php declare(strict_types=1);

function GetSaltedHash(string $pw, string $salt) : string
{
    $tmpPw   = mb_convert_encoding($pw, 'UTF-8');
    $tmpSalt = mb_convert_encoding($salt, 'UTF-8');

    $options = ['cost' => 11
              , 'salt' => $tmpSalt];

    $hBytes = password_hash($tmpPw, PASSWORD_BCRYPT, $options);

    return base64_encode($hBytes);
}

function CreateNewSalt(int $size) : string
{
    # default size
    if($size < 22)
        $size = 22;

    return base64_encode(random_bytes($size));
}

$pass = 'hello';
$size = 30;
$salt = CreateNewSalt($size);
$hash = GetSaltedHash($pass, base64_decode($salt));
$decd = base64_decode($hash);

print 'base64 encoded: ' . $hash . PHP_EOL;
print 'base64 decoded: ' . $decd . PHP_EOL;
print PHP_EOL;

if(TRUE === password_verify($pass, $decd))
    print 'The password is valid';

else
    print 'Validation failed';

print PHP_EOL;

See also:

1

Hello,

I just saw your question, so according to FB best practises:

Use images that are at least 1200 x 630 pixels for the best display on high resolution devices. At the minimum, you should use images that are 600 x 315 pixels to display link page posts with larger images. Images can be up to 8MB in size.

If your image is smaller than 600 x 315 px, it will still display in the link page post, but the size will be much smaller.

We've also redesigned link page posts so that the aspect ratio for images is the same across desktop and mobile News Feed. Try to keep your images as close to 1.91:1 aspect ratio as possible to display the full image in News Feed without any cropping.

And last:

The minimum image size is 200 x 200 pixels. If you try to use an image smaller than this you will see an error in the Sharing Debugger.

Source: https://developers.facebook.com/docs/sharing/best-practices#images

1

@Dani

... And regarding Nginx, if you were able to get Nginx to work with PUT and PATCH, please let me know how! Whenever I try, Nginx short circuits and returns back a status of 501 not implemented and with a message body of "This method may not be used."

From my understanding, you can compile Nginx with a module to override this, and enable PUT, PATCH, and DELETE but when doing so, Nginx again short circuits PHP and actually PUTS/DELETEs files in the file system!

I have tried that and, yes, it works like in your description but only if webdav is enabled for that location. Otherwise it works like in pty's example.

For a basic test try:

<?php

$stream = [];
$method = $_SERVER['REQUEST_METHOD'];

parse_str(file_get_contents('php://input'), $stream);

print "Method $method" . PHP_EOL;
print print_r($stream, TRUE) . PHP_EOL;

And then send requests:

http --form PUT http://site/script.php msg="hello" --verbose

And you should see something like:

PUT /a.php HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Length: 9
Content-Type: application/x-www-form-urlencoded; charset=utf-8
User-Agent: HTTPie/0.9.2

msg=hello

HTTP/1.1 200 OK
Connection: keep-alive
Content-Encoding: gzip
Content-Type: text/html; charset=UTF-8
Server: nginx/1.6.2
Transfer-Encoding: chunked

Method PUT
Array
(
    [msg] => hello
)
1

Check arp-scan -ln it outputs something like this:

> arp-scan -ln
Interface: wls1, datalink type: EN10MB (Ethernet)
Starting arp-scan 1.8.1 with 256 hosts (http://www.nta-monitor.com/tools/arp-scan/)
192.168.0.1     00:c0:9f:09:b8:db       QUANTA COMPUTER, INC.
192.168.0.5     00:02:a5:90:c3:e6       Compaq Computer Corporation
192.168.0.87    00:0b:db:b2:fa:60       Dell ESG PCBA Test
192.168.0.90    00:02:b3:06:d7:9b       Intel Corporation
192.168.0.153   00:10:db:26:4d:52       Juniper Networks, Inc.
192.168.0.191   00:01:e6:57:8b:68       Hewlett-Packard Company
192.168.0.196   00:30:c1:5e:58:7d       HEWLETT-PACKARD

7 packets received by filter, 0 packets dropped by kernel
Ending arp-scan 1.8.1: 256 hosts scanned in 1.628 seconds (157.25 hosts/sec). 7 responded

And you could simply parse the output. But I'm not sure if there is a version for Windows platforms. Some info here:

1

i am just curious how to access social media accounts like facebook, watspp etc. with the users' permission in order to help them prevent unethical hackers from breaking into their accounts.

Even if ethical, that would probably be a misuse of FaceBook terms of services. There are projects, like BugCrowd, which allows you to hack into a service, limiting the activity to specific targets requested by the owner and following specific rules: non disclosure & co. Facebook partecipates to that, and usually pays bounties through their system. So, if you are really interested check it out: https://bugcrowd.com/