cereal 1,524 Nearly a Senior Poster Featured Poster

Yes, in MySQL, RLIKE is a synonym of REGEXP:

cereal 1,524 Nearly a Senior Poster Featured Poster

FIND_IN_SET() does not use indexes, so it can become slow. You can try with a regular expression and LIKE:

SELECT `column` FROM `table` WHERE `column` LIKE '123%' AND `column` RLIKE '123[0-9]{0,3}';

See this post for more information:

cereal 1,524 Nearly a Senior Poster Featured Poster

No, zero issues until now, all is fine.

cereal 1,524 Nearly a Senior Poster Featured Poster

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

More precisely like this:

<?php

$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;
cereal 1,524 Nearly a Senior Poster Featured Poster

I'm following the Redis, PHPRedis documentation and the CI driver to see if there is any discrepancy that could lead those results. But as far as I'm seeing it seems all fine in your code.

Only few notes on PHPRedis, I don't know if it helps you:

A) set() used by CI save() switches to setex() if the value is an integer, I don't know if this changes something for you or if you are using an old release of Redis or PHPRedis that could generate a race condition, for example the behaviour of this method changes between PHPRedis 2.2.7 and 2.2.8;

B) delete() in the latest stable CI driver is doing:

/**
 * Delete from cache
 *
 * @param   string  $key    Cache key
 * @return  bool
 */
public function delete($key)
{
    if ($this->_redis->delete($key) !== 1)
    {
        return FALSE;
    }

    if (isset($this->_serialized[$key]))
    {
        $this->_serialized[$key] = NULL;
        $this->_redis->sRemove('_ci_redis_serialized', $key);
    }

    return TRUE;
}

but on PHPRedis the delete() method can accept multiple parameters: as string or as array:

$r->delete('key_1', 'key_2');
$r->delete(['key_1', 'key_2']);

And in both cases it will return 2 not 1 nor a boolean. So, IMHO, this statement:

if ($this->_redis->delete($key) !== 1)

is not always correct: the statement is TRUE as long it does not return 1, i.e. when:

  • it returns 0 because the key does not exists;
  • or when, and if, you submit an array with multiple keys.

Now, I don't know if you are using the delete() method somewhere in the code, but if an array …

cereal 1,524 Nearly a Senior Poster Featured Poster

Hi,

look, this hex dump suggests it could be C++:

0007e0a0  72 20 61 72 67 75 6d 65  6e 74 73 0d 0a 00 00 00  |r arguments.....|
0007e0b0  52 36 30 30 32 0d 0a 2d  20 66 6c 6f 61 74 69 6e  |R6002..- floatin|
0007e0c0  67 20 70 6f 69 6e 74 20  6e 6f 74 20 6c 6f 61 64  |g point not load|
0007e0d0  65 64 0d 0a 00 00 00 00  4d 69 63 72 6f 73 6f 66  |ed......Microsof|
0007e0e0  74 20 56 69 73 75 61 6c  20 43 2b 2b 20 52 75 6e  |t Visual C++ Run|
0007e0f0  74 69 6d 65 20 4c 69 62  72 61 72 79 00 00 00 00  |time Library....|
0007e100  0a 0a 00 00 52 75 6e 74  69 6d 65 20 45 72 72 6f  |....Runtime Erro|
0007e110  72 21 0a 0a 50 72 6f 67  72 61 6d 3a 20 00 00 00  |r!..Program: ...|
0007e120  2e 2e 2e 00 3c 70 72 6f  67 72 61 6d 20 6e 61 6d  |....<program nam|
0007e130  65 20 75 6e 6b 6e 6f 77  6e 3e 00 00 00 00 00 00  |e unknown>......|

And this:

0008ead0  46 53 4f 55 4e 44 20 50  72 69 6d 61 72 79 20 4d  |FSOUND Primary M|
0008eae0  69 78 42 75 66 66 65 72  00 00 00 00 43 3a 5c 64  |ixBuffer....C:\d|
0008eaf0  65 76 5c 66 6d 6f 64 33  36 30 73 72 63 5c 73 72  |ev\fmod360src\sr|
0008eb00  63 5c 66 73 6f 75 6e 64  2e 63 00 00 43 3a 5c 64  |c\fsound.c..C:\d|
0008eb10  65 76 5c 66 6d 6f 64 33  36 30 73 72 63 5c 73 72  |ev\fmod360src\sr|
0008eb20  63 5c 66 73 6f 75 6e 64  5f 73 61 6d 70 6c 65 2e  |c\fsound_sample.|
0008eb30  63 00 00 00 4d 65 6d 6f  72 79 20 66 69 6c 65 00  |c...Memory file.|

points to http://www.blitzbasic.com/ tools. See if they can help you.

cereal 1,524 Nearly a Senior Poster Featured Poster

@Dani I think it's related more to prepared statements in ext/mysqli:

@Sunny

See if this comment helps:

Note: when uploading a blob consider to convert it into a string, otherwise look at:

cereal 1,524 Nearly a Senior Poster Featured Poster

It is not automatic. When you call /main/ you point to a directory (aka folder) in the document root of the web server, to display by default a file you need to configure the server. This depends on the DirectoryIndex directive, if you are using Apache. The documentation says:

The DirectoryIndex directive sets the list of resources to look for, when the client requests an index of the directory by specifying a / at the end of the directory name. [...] Several URLs may be given, in which case the server will return the first one that it finds. If none of the resources exist and the Indexes option is set, the server will generate its own listing of the directory.

Source: https://httpd.apache.org/docs/current/mod/mod_dir.html#directoryindex

So you could have a list of available indexes:

DirectoryIndex default.htm index.php index.cgi index.html

and if inside /main/ you have both default.htm and index.php the server will load default.htm because of its precedence in the directive listing.

cereal 1,524 Nearly a Senior Poster Featured Poster

Hi,

you have two choices:

  1. parse the CSV strings into an array and then insert
  2. use the LOAD DATA INFILE statement to feed the file to the database, but it requires to have access to a folder that is readable by the MySQL server

For an example of the first case see this thread on SO:

Basically you send the result of the curl execution to a temporary file and parse it through fgetcsv():

<?php

$url = 'http://localhost/return_csv.php';
$f   = fopen('php://temp', 'w+');
$ch  = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
curl_setopt($ch, CURLOPT_FILE, $f);
curl_exec($ch);
curl_close($ch);

rewind($f);

try {

    $db = new PDO('sqlite:./data.db');
    $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $db->beginTransaction();

    $stmt = $db->prepare('INSERT INTO `test` (`var1`, `var2`, `var3`, `var4`, `var5`) VALUES(?, ?, ?, ?, ?)');

    while($csv = fgetcsv($f))
        $stmt->execute($csv);

    $db->commit();
}

catch(PDOException $e) {
    $db->rollback();
    die('Database error: ' . $e->getMessage() . PHP_EOL);
}

catch(Exception $e) {
    die('Error: ' . $e->getMessage() . PHP_EOL);
}

finally {
    fclose($f);
}

See:

cereal 1,524 Nearly a Senior Poster Featured Poster

Hi,

set the the rewrite base to your subfolder RewriteBase "/myapp/", then it should work. For more information read this:

cereal 1,524 Nearly a Senior Poster Featured Poster

Hi,

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

Docs:

cereal 1,524 Nearly a Senior Poster Featured Poster

The error states:

(previously declared in C:\wamp\www\mysqltopdf\fpdf.php:36) in C:\wamp\www\mysqltopdf\fpdf.php on line 52

so check the contents of included file. Also I don't know much about this code, so verify if the two functions are doing the same action or if they just have the same name.

cereal 1,524 Nearly a Senior Poster Featured Poster

@athanas_1

Hi, this error happens when you declare a function two or more times. For example:

<?php

function a() {
    return ;
}

function a() {
    return ;
}

You can fix it by removing the second declaration.

cereal 1,524 Nearly a Senior Poster Featured Poster

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.

rproffitt commented: Exploits. Exploits everywhere (insert meme here) +11
cereal 1,524 Nearly a Senior Poster Featured Poster

Spaces in URLs can be represented by %20 or by +, it depends on the browser and by the enctype attribute of the form tag.

Your script can receive requests like these:

term=abc++++
term=abc%20%20%20%20

Which in your code equals to:

string(7) "abc    "

So, instead of $searchTerm = $_GET['term']; do:

$searchTerm = trim(filter_input(INPUT_GET, 'term', FILTER_SANITIZE_STRING));

And the script will process the intended input:

string(3) "abc"

Note, in this case you don't need to use urldecode() as superglobals are already decoded. Also, you should query the database through prepared statements.

cereal 1,524 Nearly a Senior Poster Featured Poster

Ok, the blank list of results happens because JQuery expects to receive label and/or value as index keys of the result set.

Multiple types supported:
Array: An array can be used for local data. There are two supported formats:

  • An array of strings: [ "Choice1", "Choice2" ]
  • An array of objects with label and value properties: [ { label: "Choice1", value: "value1" }, ... ]

The label property is displayed in the suggestion menu. The value will be inserted into the input element when a user selects an item. If just one property is specified, it will be used for both, e.g., if you provide only value properties, the value will also be used as the label.

Source: http://api.jqueryui.com/autocomplete/#option-source

So change desc1 to label and should work fine. I was testing with a custom table which had a label column, so the issue didn't show up to me.

Do:

<script type="text/javascript">
    $(function() {

        $("#party").autocomplete({
            minLength: 0,
            source: "autocomplete.php",
            focus: function(event, ui) {
                $("#party").val(ui.item.label);
                $("#code").val(ui.item.code);
                return false;
            },
            select: function(event, ui) {
                $("#party").val(ui.item.label);
                $("#code").val(ui.item.code);
                return false;
            }
        })
    });
</script>

And in the PHP side:

$i = 0;
while($row=sqlsrv_fetch_array($select)) 
{
    $data[$i]['code']  = $row['code'];
    $data[$i]['label'] = $row['desc1'];
    $i++;
}
cereal 1,524 Nearly a Senior Poster Featured Poster

Can you show your current code? (HTML, JS and PHP)
The above results seem to be originated by your previous code.

cereal 1,524 Nearly a Senior Poster Featured Poster

Look, it works fine for me. Do this: open the Web Developer Console which is available in Google Chrome, Chromium and Mozilla Firefox, hit the Network tab and enter a letter in the autocomplete input field, you should see a request to the server, hit the request link and click the Response tab, you should see a JSON object with the rows.

cereal 1,524 Nearly a Senior Poster Featured Poster

Try with:

$i = 0;
while($row=sqlsrv_fetch_array($select)) 
{
    $data[$i]['code'] = $row['code'];
    $data[$i]['desc1'] = $row['desc1'];
    $i++;
}
cereal 1,524 Nearly a Senior Poster Featured Poster
cereal 1,524 Nearly a Senior Poster Featured Poster

Hi,

check the source of the custom data example in the autocomplete JQueryUI documentation:

The select property should fit your requirements:

select: function( event, ui ) {
    $( "#project" ).val( ui.item.label );
    $( "#project-id" ).val( ui.item.value );
    $( "#project-description" ).html( ui.item.desc );
    $( "#project-icon" ).attr( "src", "images/" + ui.item.icon );

    return false;
  }

Another example: https://jsfiddle.net/0wdbgage/

cereal 1,524 Nearly a Senior Poster Featured Poster

Hi,

with browsers requests, the server can only accept the upload and check the sizes when it finishes. So, if you want to manage the error through PHP, raise the size and set a lower limit in the script.

If the limit in the php.ini file is 25MB and the server gets a bigger request body, then you will not see an error response. But the error log should return some information. The server can also handle the request by limiting the body request size and return an error.

You can check the file size with javascript, before the upload starts, see this snippet:

This will not stop malicious users, but it can be user-friendly solution.

<rant>
If browsers worked properly then they would wait for a HTTP/1.1 100 CONTINUE response from the server: the client in this case must send the file size through an header, wait for the server to validate the request and then proceed or discard. That would be wonderful to save bandwidth.
</rant>

diafol commented: good link - bookmarked :) +15
cereal 1,524 Nearly a Senior Poster Featured Poster

Hi,

right before this code, set a check:

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

Too see why the connection returns null.

cereal 1,524 Nearly a Senior Poster Featured Poster

Hi, you could use the replication model shipped with MySQL, see:

Where each node acts like master and slave. See if a multi-master approach could work:

cereal 1,524 Nearly a Senior Poster Featured Poster

Hi,

you have to share more information about the issue, the form and the controller code could also help.

cereal 1,524 Nearly a Senior Poster Featured Poster

Can you try again and let me know if the results are as you intend them this time?

You're awesome Dani, now it works fine, thank you! :D

cereal 1,524 Nearly a Senior Poster Featured Poster

Thank you Dani,

no way, by following your directions I get:

A different DaniWeb member is already associated with this Dazah user account.

Let me recap:

  • my current account (cereal) is the first account;
  • I used to login by submitting email address & password;
  • when the Dazah sign in procedure was introduced, I was not able to access, so I used Google G+, which in practice pointed to the same email address of my manual sign in;
  • by using Google G+ I thought I could merge it with my current account, instead I got a brand new account (_1);
  • the new account, however, got private messages, karma points, endorsments;
  • when I wrote you about the issue, through email messages, you fixed by moving back some data to the first account (cereal);
  • since then has been mess.

I suppose this is caused by the email address, so I applied plus addressing to both Dazah accounts (+alpha & +bravo) to understand if this makes a difference:

  • if I manually sign in through +alpha which should be cereal and instead it appears to be _1, and I try to Continue as +alpha, I get:

    A different DaniWeb member is already associated with this Dazah user account.

  • if I click switch user I get back to the Dazah login page

  • if I sign in through Google G+ which should be _1 I end up into +bravo which is cereal

  • if I …
cereal 1,524 Nearly a Senior Poster Featured Poster

Hi Dani! :D

I have few points:

A

I still not receive emails (newsletter, notifications) with my registration email address (the Receive Community-related Email? issue). I only receive the monthly newsletter with the email address of the other account. To watch an article I have to use that account from another browser, otherwise I don't get anything.

B

My old private messages are all in the other account.

C

I edited my Dazah profile to NOT display my name, but here in the forum is still shown in my Profile & CV pages.

Sincerly, I'm here just to ask or reply few questions in the forums, not to network. I think I've understood what you want to achieve, but these changes made me feel a bit unconfortable.

cereal 1,524 Nearly a Senior Poster Featured Poster

I'm talking more about the darkest real possibilities.

Like executing arbitrary code through the font engine? That's definitely doable by crafting fonts with embedded code. See, for example, the blend vulnerability:

cereal 1,524 Nearly a Senior Poster Featured Poster

Consider also that you could serve Google Fonts from your web server, just download them and set the paths in the CSS file.

cereal 1,524 Nearly a Senior Poster Featured Poster

Hi,

are you following the documentation?

If affirmative, can you share your code and more information about what is not working?

cereal 1,524 Nearly a Senior Poster Featured Poster

At line 36 add:

or die(mysql_error());

and see if it returns some information about the query syntax. By the way, you should switch to MySQLi or PDO. The mysql_* functions have been removed from PHP 7.0, so you will have hard time when upgrading. See:

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

You can use Apache Bench to test loads:

It allows you to build GET & POST requests, file uploads and see how the server performs under the defined conditions.

cereal 1,524 Nearly a Senior Poster Featured Poster

Hi,

add error checking to the database connection and query execution, if it does not solve, test your query on a MySQL client.

cereal 1,524 Nearly a Senior Poster Featured Poster

Hi,

in addition to Ddanbe's suggestion: with Google Chrome, right click a word in this post, choose Inspect, it will open the Web Developer Console, click on Computed: from there you get all the style information about the inspected element.

cereal 1,524 Nearly a Senior Poster Featured Poster

Hi,

if you want to download the project to a new box then you clone it, so you do:

git clone url_of_the_repository

If the code is already there, but not updated to the latest version, then you just pull:

git pull

and then you can push the changes. See:

diafol commented: good, as always :) +15
cereal 1,524 Nearly a Senior Poster Featured Poster

-sigh-
Why is it so, that when there's an issue, people look all around :D, but not on the issue.

lol, I asked because I do not know how you are implementing that statement and what you really expect to get. What do you mean by true 404? A redirect to the 404 error page defined by the server?

This:

While Opera fools itself, Firefox doesn't. It shows just super-empty document (not 404, but also not even standard CSS stylesheet). How do I successfully send "404 Not Found" to ALL browser.

is not a useful information, to understand your issue.

Look, to me it's easier to move the includes scripts into a separated directory, then use .htaccess to deny direct access to that directory, so it cannot be accessed through the browser.

This solution does not require to modify the scripts, so nothing like the header() 404 statement, if really needed you could force it through .htaccess and send a more appropriate 403 or even 404.

It's even better if you move the includes directory to the parent of the public_html directory, which if correctly set, is not accessible by the browsers, that way you don't even need to use .htaccess file to define what is accessible and what not.

diafol commented: GSOH! +15
cereal 1,524 Nearly a Senior Poster Featured Poster

Hi,

I don't understand your request: defined() is used only with constants not with statements, are you defining a constant or just trying to include 'somefile.php'; and be sure it's loaded?

cereal 1,524 Nearly a Senior Poster Featured Poster

Hi,

It happens because of rounding errors, for more information see:

You could try with Decimal():

from decimal import Decimal

# with binary floating points
print(divmod(356, 3.56))
(99.0, 3.5599999999999947)

# with arbitrary roundings
print(Decimal('356') % Decimal('3.56'))
0.0

Example: http://ideone.com/a6UDRi

cereal 1,524 Nearly a Senior Poster Featured Poster

Hi,

can you show the code that gives you this issue?

cereal 1,524 Nearly a Senior Poster Featured Poster

See this comment:

You can connect to MSSQL through different drivers, depending on which you choose then you can use rowCount().

cereal 1,524 Nearly a Senior Poster Featured Poster

Hi,

if using MySQL you can do a second query:

$num = $this->conn->query("SELECT FOUND_ROWS()")->fetchColumn();

About rowCount():

PDOStatement::rowCount() returns the number of rows affected by the last DELETE, INSERT, or UPDATE statement executed by the corresponding PDOStatement object.

If the last SQL statement executed by the associated PDOStatement was a SELECT statement, some databases may return the number of rows returned by that statement. However, this behaviour is not guaranteed for all databases and should not be relied on for portable applications.

See also this comment, it suggests how to add a custom method with FOUND_ROWS():

cereal 1,524 Nearly a Senior Poster Featured Poster

Hi,

start from the ground:

  • install a local development environment to test your scripts, so search tutorials about installing PHP and MySQL, or if you want something more easy to manage, search for XAMMP, LAMP & co.
  • then search tutorials about PHP and MySQL, for example "how to create a blog in PHP" would be a good start

After that, if you have doubts, use search engines and try, read the documentation in the PHP and MySQL websites and if you really don't find a solution then ask for help.

cereal 1,524 Nearly a Senior Poster Featured Poster

Hi,

have you tried the web developer console integrated in your browser (Mozilla Firefox, Chrome, Chromium) to see if the javascript code is raising some errors?

Can you provide a live example?

Besides, test your script with a simple HTML form, you will see there are at least few issues:

Issue 1
move_uploaded_file($_FILES["fileUpload"]["tmp_name"],WWW_ROOT.$dirname."/".$_FILES["file"]["name"]);

In the first parameter you refer to fileUpload, in the second to file, so it's like if your are trying to get the values from two different arrays. Fix them to match fileUpload as defined in the javascript.

Issue 2

This involves multiple lines:

/// client side
<input id="serverUrl" type="text" value="http://sample.com/mobile_app/upload_img.php" />

/// server side
$dirname = "./user_img";
mkdir ($dirname, 0777, true); 
move_uploaded_file($_FILES["fileUpload"]["tmp_name"],WWW_ROOT.$dirname."/".$_FILES["file"]["name"]);

If you define $dirname with a relative path, then the upload_img.php script will create the directory inside his own path, so you end with:

/mobile_app/user_img/

The move_uploaded_file() function, instead, points to the document root, and you get something like this:

/./user_img/

The mover function will not find the path, so it will fail to complete the task. However, the $_FILES array gets populated before these things happen, so it may not affect your current issue.

Issue 3

The mkdir() will raise a warning as soon you run the script successfully for the second time, because the path already exists. Use file_exists() to verify if it exists, or just create it manually and remove mkdir().

cereal 1,524 Nearly a Senior Poster Featured Poster

@zebnoon1 Hi, you were asked multiple times, to reply to some questions with useful information. Calmly read again Pritaeas posts and reply to his requests.

For example, he asked:

What size is the downloaded file?

So the downloaded .pdf file is 0 bytes, few bytes and when opens is like corrupted? Have you tried to open the file into your PHP editor? Because it could be a plain-text file (with .pdf extension) and more importantly with a PHP error generated by your script. If this is so, then that error could help a lot to understand what happens.

So read again Pritaeas posts and reply to his requests.

pritaeas commented: :) +15
cereal 1,524 Nearly a Senior Poster Featured Poster

Hi,

change the DB_IStatement_1 signature for the execute() and fetch() methods and it should work fine. In practice you are implementing the PDOStatement interface into your class, so you must declare the same arguments:

public function execute($params = []);
public function fetch($how = NULL, $orientation = NULL, $offset = NULL);

Here's few examples with the same error and fixed:

More information:

Bye!

cereal 1,524 Nearly a Senior Poster Featured Poster

Hi, we need more information about your issue: the code, what is expected to and what you get. If you can, add a JS fiddle, it would help.

cereal 1,524 Nearly a Senior Poster Featured Poster

Hello,

you can use a stored procedure, for example:

DROP PROCEDURE IF EXISTS `calcTotals`;
DELIMITER //
CREATE PROCEDURE `calcTotals`(IN `loanStatus` VARCHAR(100), IN `settlementStatus` VARCHAR(100))
BEGIN
    DECLARE `total_loan` DECIMAL(10,2);
    DECLARE `total_settlement` DECIMAL(10,2);
    SELECT SUM(`total_amount`) INTO `total_loan` FROM `loan` WHERE `loan_status` = `loanStatus`;
    SELECT SUM(`amount`) INTO `total_settlement` FROM `settlement` WHERE `sett_status` = `settlementStatus`;
    SELECT `total_loan`, `total_settlement`;
END
//
DELIMITER ;

And then run it like this:

CALL calcTotals('not finish', 'Active');

It will return something like:

+------------+------------------+
| total_loan | total_settlement |
+------------+------------------+
|     550.00 |            75.00 |
+------------+------------------+
1 row in set (0.00 sec)
cereal 1,524 Nearly a Senior Poster Featured Poster

Hi,

see the lines 254 and 263 of the PHP page, the first checks if the token is set by the request (i.e. through javascript), the second is a conditional IF statement that verifies the value of the set token with the hardcoded.

Change the value in the javascript and, accordingly, in the PHP file.

cereal 1,524 Nearly a Senior Poster Featured Poster

Hi Simon,

I think your issue is given by the configuration of your local Apache server. From what I have understood you are not configuring a VirtualHost for your project. You are simply creating a new directory (folder) into the document root of the default Apache host.

By doing this, you have to tell the rewrite engine to check the correct path before trying to apply the rewrite rules. For example, these will apply to the document root:

# first .htaccess
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^new/([0-9]+)/?$ new.php?msgID=$1 [L]
</IfModule>

So it will try to rewrite the url starting from //localhost/, instead, the following will apply to the project folder:

# second .htaccess
<IfModule mod_rewrite.c>
    RewriteEngine On
    RewriteBase /WallScript/
    RewriteCond %{REQUEST_FILENAME} !-f
    RewriteCond %{REQUEST_FILENAME} !-d
    RewriteRule ^new/([0-9]+)/?$ new.php?msgID=$1 [L]
</IfModule>

So, it will start from //localhost/WallScript/. It depends on the value assigned to the RewriteBase directive:

RewriteBase /WallScript/

Here an example of the folder structure:

/
├── functions.php
├── .htaccess
├── index.php
├── new.php
└── WallScript
    ├── .htaccess
    └── new.php

To recap: the first .htaccess applies to the /new.php file, i.e. the file placed in the document root, the second applies to the /WallScript/new.php file.

By default Apache inherits the .htaccess rules to the subfolders, so if the configuration allows it, you can avoid to write multiple .htaccess and place just one in the document root.

The R=301 flag that I suggested in my previous posts, was to test which file was …