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.


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.


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.



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';

    print 'Validation failed';

print PHP_EOL;

See also:



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



... 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:


$stream = [];

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


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
    [msg] => hello

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/)     00:c0:9f:09:b8:db       QUANTA COMPUTER, INC.     00:02:a5:90:c3:e6       Compaq Computer Corporation    00:0b:db:b2:fa:60       Dell ESG PCBA Test    00:02:b3:06:d7:9b       Intel Corporation   00:10:db:26:4d:52       Juniper Networks, Inc.   00:01:e6:57:8b:68       Hewlett-Packard Company   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:


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/



it does not work because you are not accessing to the returned row when you call $stmt->otdq_ordernum.


$row = $stmt->fetch();

And then:


Or use a MySQL variable.

Also rowCount() in PDO, assuming you are using it, does not return the rows found in a SELECT statement, but only the rows affected by INSERT, UPDATE, DELETE & similar statements.



I was supposing the $_POST['Net'] arrays to hold float values, not file names. Anyway you could write:

$files    = [];
$products = [];

while($rowProduct = mysql_fetch_array($productSQL))
    $products[] = $rowProduct['POProductNet'];

if(TRUE === isset($_POST['Net']) && TRUE === is_array($_POST['Net']))
    $files = array_map('basename', $_POST['Net']);
    $diff  = array_diff_assoc($products, $files);

    if(count($diff) > 0)
        // write data to db

Here I'm just using the array functions, instead of the loops, it's just a choice. You can go with loops.

But if $_POST['Net'] is supposed to always be an array, then I would check it in the sanitizing step, not after the query to the database. So it would look like more:


if(FALSE !== $net)
    $files    = array_map('basename', $net);
    $products = [];

    // select query the database
    // populate the $products array
    // compare with $files



just to add something: the first step to avoid spam filters is to setup SPF and DKIM in the TXT records of the domain. That way Google, Hotmail & co. can verify if the sender address is allowed and if the origin is correct. For example, take Daniweb setup:

# query Google DNS
> dig daniwebmail.com ANY @

daniwebmail.com.    299 IN  MX  5 daniwebmail-com.mail.protection.outlook.com.
daniwebmail.com.    299 IN  A
daniwebmail.com.    299 IN  TXT "MS=ms74324738"
daniwebmail.com.    299 IN  TXT "v=spf1  include:spf.protection.outlook.com ip4: ip4: ip4: a mx include:_spf.google.com ~all"

The TXT record is saying from which IP addresses the emails should be considered valid, this includes a range of IPs, the mail server defined in the MX record and the IP from the A record.

For example last newsletter came from community@daniwebmail.com and from IP With spfquery you can test the validity of the origin:

spfquery -guess "v=spf1 mx a -all" -ip -sender community@daniwebmail.com

The response looks like this:


spfquery: domain of daniwebmail.com designates as permitted sender
Received-SPF: pass (spfquery: domain of daniwebmail.com designates as permitted sender) client-ip=; envelope-from=community@daniwebmail.com;

Which is basically what are doing mail services when receiving an email message. If the SPF is genuine then there are good chances to avoid the SPAM folder. But at that point it's necessary to act like you wrote, by rate limiting messages and by choosing correct phrasing.

More info:


Votes + Comments
Good info

You could use the RecursiveDirectoryIterator() something like in this comment:

More precisely like this:


$path = dirname(__DIR__);

$dir_iterator = new RecursiveDirectoryIterator($path
                     , FilesystemIterator::SKIP_DOTS);

$iterator     = new RecursiveIteratorIterator($dir_iterator
                    , RecursiveIteratorIterator::LEAVES_ONLY
                    , RecursiveIteratorIterator::CATCH_GET_CHILD);

foreach($iterator as $file)
    if(TRUE === $file->isReadable())
        echo $file . PHP_EOL;


from the documentation the strtotime() function you can read:

Parse about any English textual datetime description into a Unix timestamp

And it expects:

int strtotime ( string $time [, int $now = time() ] )

The $stockdate is a DateTime object, not a string. So try by submitting the string:

date('l F d, Y', strtotime($stockdate->date));

Or follow the DateTime library:

print $stockdate->format('l F d, Y');



In addition: if the hash is generated by a salted md5 or sha1, the attacker can generate a string that outputs the same hash, it does not need to find the exact password, it just need to find a collision. See:

That would not work on Google, but it can work on other web services that are storing passwords as md5 or sha1 hashes. In some cases, you could see that the collision string does not work, for the only reason that the Z webiste is storing passwords in plain text :D

If I can suggest, change the passwords everywhere and activate the 2FA:

Also, it's a good practice to use plus addressing when signing in new services, as example name+zwebsite@gmail.com so, if you get spammy messages, you have a chance to find out the source. Plus addressing also works in Hotmail.

By the way, I use this service to get data breaches notices:

It works well.

Votes + Comments
Exploits. Exploits everywhere (insert meme here)