0

I ma pretty sure I need something like a preg_replace in this situation but I am not sure and if so where to put it. I have a page that allows people to search an employee directory (PHP and MSSQL). They can search by last name, building or by department. the last name and building are fine but I have the problem with three of our departments, two have an & in them (ie. Grants & Planning) and when you click on that department it doesn't return any results and I think it is because it is not recognizing the "& planning" as part of a whole string. The other problem I have is that I have one department that has a ' in it and it throws an error

  • PHP Warning: mssql_query() [function.mssql-query]: message: Line 1: Incorrect syntax near 's'. (severity 15) in C:\Inetpub\wwwroot\DACC\directory\dept.php on line 179

    *PHP Warning: mssql_query() [function.mssql-query]: message: Unclosed quotation mark before the character string ' ORDER BY Lastname'. (severity 15) in C:\Inetpub\wwwroot\DACC\directory\dept.php on line 179*

Line 179 is this... $query = mssql_query("SELECT * FROM directory WHERE Displayname = '$department' ORDER BY Lastname");

Here is the rest of the code for the query page for by department.... if anyone can help me I would greatly appreciate it! `

$department = $_GET['dept'];

 // This will evaluate to TRUE so the text will be printed.
 if (isset($department)) {
 $query = mssql_query("SELECT * FROM directory WHERE Displayname = '$department' ORDER BY Lastname");//$query = mssql_query("SELECT * FROM directory WHERE department IN (SELECT id FROM departments WHERE name='$department') ORDER BY Lastname");
 $query2 = mssql_query(
 "SELECT TOP 1 directory.FirstName, directory.Lastname, directory.email,
 directory.phone, directory.office, directory.title, directory.displayname,                departments.id AS dept_id, departments.name AS dept_name, departments.url AS dept_url
 FROM directory
 INNER JOIN departments on directory.displayname = departments.name
 WHERE directory.displayname = '$department'
 ORDER BY directory.LastName");
 $numofrows = @mssql_num_rows($query);
 // Check if there were any records
 if (!mssql_num_rows($query)) {
echo 'No records found';
echo '<br /><a href="/directory/">Go Back</a>';
 } else {
 while($row1 = mssql_fetch_array($query2))
   {
  $dept_var = $row1['dept_name'];
 $dept_id = $row1['dept_id'];
 $dept_url = $row1['dept_url'];
    print "<h3><a href=\"$dept_url\">$dept_var</a></h3>";
 }
 print "<table id=\"directory_table\" width=\"480\">
 <tr>
 <th>Name</th>
 <th>Email</th>
 <th>Phone</th>
 <th>Office</th>
 <th>Title</th>
 </tr>";    
 for($i = 0; $i < $numofrows; $i++) 
{
$row = mssql_fetch_array($query);
    if($i % 2) 
    { 
    print '<tr bgcolor="#ffffff">';
    } 
else 
    { 
    print '<tr bgcolor="#eeeeee">';
    }

    print "<td>" . $row['Firstname'] . " " . $row['Lastname'] . "&nbsp;&nbsp;</td>";
    print "<td><a href=\"mailto:" . $row['email'] . "\">" . $row['email']. "</a>&nbsp;&nbsp;</td>";
    print "<td>" . $row['phone'] . "&nbsp;&nbsp;</td>";
    print "<td>" . $row['Office'] . "&nbsp;&nbsp;</td>";
    print "<td>" . $row['Title'] . "&nbsp;&nbsp;</td>";
    print "</tr>";
}
 print "</table>";
 }
 // Free the query result
 mssql_free_result($query);
 }
 else
 print "No Search Defined";
 ?>

EDITED to show changes ok tried this:

    $serverName = "localhost"; //serverName\instanceName
    $connectionInfo = array( "Database"=>"DACC", "UID"=>"daccweb", "PWD"=>"go");
    $conn = sqlsrv_connect( $serverName, $connectionInfo);

if( $conn ) {
 echo "Connection established.<br />";
}else{
 echo "Connection could not be established.<br />";
 die( print_r( sqlsrv_errors(), true));
}
//$conn = sqlsrv_connect("connection string here");
$queryParams = array($department);


//Selector links
print "<a href=\"/directory/\">Go back to main search</a><br />";
print "<u>Search for Employees:</u><br /><br />\n";

print "<br />";





//$officeloc = $_GET['building'];
$department = $_GET['dept'];

// This will evaluate to TRUE so the text will be printed.
if (isset($department)) {


$query = sqlsrv_query($conn, "SELECT * FROM directory WHERE Displayname = ? ORDER BY Lastname", $params);

$query2 = sqlsrv_query($conn, "SELECT TOP 1 directory.FirstName, directory.Lastname, directory.email,
directory.phone, directory.office, directory.title, directory.displayname,
 departments.id AS dept_id, departments.name AS dept_name, departments.url AS dept_url
 FROM directory
INNER JOIN departments on directory.displayname = departments.name
WHERE directory.displayname = ?
ORDER BY directory.LastName", $params);

NEW EDIT
query runs but doesn't echo/print results $query = sqlsrv_query($conn, "SELECT * FROM directory WHERE Displayname = ? ORDER BY Lastname", $params);

$query2 = sqlsrv_query($conn, "SELECT TOP 1 directory.FirstName, directory.Lastname, directory.email,
directory.phone, directory.office, directory.title, directory.displayname,
departments.id AS dept_id, departments.name AS dept_name, departments.url AS dept_url
FROM directory
INNER JOIN departments on directory.displayname = departments.name
WHERE directory.displayname = ?
ORDER BY directory.LastName", $params);


$numofrows = @@sqlsrv_has_rows($query);

// Check if there were any records
if (!@sqlsrv_has_rows($query)) {
echo 'No records found';
echo '<br /><a href="/directory/">Go Back</a>';
} else {



while($row1 = sqlsrv_fetch_array($query2))
  {
    $dept_var = $row1['dept_name'];
    $dept_id = $row1['dept_id'];
    $dept_url = $row1['dept_url'];


   print "<h3><a href=\"$dept_url\">$dept_var</a></h3>";
  //echo "</h3><br />";
    }



    print "<table id=\"directory_table\" width=\"480\">
    <tr>
<th>Name</th>
<th>Email</th>
<th>Phone</th>
<th>Office</th>
<th>Title</th>

</tr>"; 
for($i = 0; $i < $numofrows; $i++) 
{
$row = sqlsrv_fetch_array($query);
    if($i % 2) 
    { 
    print '<tr bgcolor="#ffffff">';
    } 
else 
    { 
    print '<tr bgcolor="#eeeeee">';
    }

    print "<td>" . $row['Firstname'] . " " . $row['Lastname'] . "&nbsp;&nbsp;</td>";
    print "<td><a href=\"mailto:" . $row['email'] . "\">" . $row['email']. "</a>&nbsp;&nbsp;</td>";
    print "<td>" . $row['phone'] . "&nbsp;&nbsp;</td>";
    print "<td>" . $row['Office'] . "&nbsp;&nbsp;</td>";
    print "<td>" . $row['Title'] . "&nbsp;&nbsp;</td>";
    print "</tr>";
}
print "</table>";
}

// Free the query result
sqlsrv_free_stmt($query);
}
else
print "No Search Defined";
Inky1231
  • 85
  • 4
  • 16
  • 2
    Your code is vulnerable to [SQL injection attacks](http://bobby-tables.com). Stop working on this until you've learned about them and how to avoid them. – Marc B Nov 15 '12 at 15:17
  • I didn't build this page, just trying to fix it until a full site rebuild can be accomplished. – Inky1231 Nov 15 '12 at 15:19
  • It won't be "fixed" until it's rid of vulnerabilities to SQL injection. Right now someone could likely delete everything in your database just by doing a simple search. – user428517 Nov 15 '12 at 15:23
  • possible duplicate of [Best way to prevent SQL injection?](http://stackoverflow.com/questions/60174/best-way-to-prevent-sql-injection) – Álvaro González Nov 15 '12 at 15:23
  • Alvaro, no it is not a duplicate i am not looking to prevent SQL injection I am looking on how to fix a query that doesn't like & and ' – Inky1231 Nov 15 '12 at 15:24
  • I agree that it's not a duplicate; however, by preventing SQL injection you'll automatically solve most of the problems you're having. – user428517 Nov 15 '12 at 15:26
  • Ok can you steer me in the right direction in HOW to make this a parametrized query? I have never done it before (I am still intermediate level with SQL never had to do more than straight queries). – Inky1231 Nov 15 '12 at 15:29
  • Sean's answer includes a link with lots of helpful information. I suggest reading it all. Also, on that page are links to other pages that will tell you how to use parameterized queries. – user428517 Nov 15 '12 at 15:37
  • trying a few right now, no success yet :( – Inky1231 Nov 15 '12 at 15:42

1 Answers1

3

You can use SQL parameters in PHP and MSSQL, have a look at this:

http://blogs.msdn.com/b/sqlphp/archive/2008/09/30/how-and-why-to-use-parameterized-queries.aspx

Your parameter values will automatically be escaped without any work on your part.

You'll need to use the sqlsrv driver, see: http://www.php.net/manual/en/sqlsrv.setup.php

In order to get the number of rows we need to specify some query options as well. (Take a look at http://www.php.net/manual/en/function.sqlsrv-num-rows.php and http://msdn.microsoft.com/en-us/library/hh487160.aspx)

$conn = sqlsrv_connect("connection string here");
$queryParams = array($department);
$queryOptions = array( "Scrollable" => "buffered" );
$query = sqlsrv_query($conn, "SELECT * FROM directory WHERE Displayname = ? ORDER BY Lastname", $queryParams, $queryOptions);

$query2 = sqlsrv_query($conn, "SELECT TOP 1 directory.FirstName, directory.Lastname, directory.email,
directory.phone, directory.office, directory.title, directory.displayname,
departments.id AS dept_id, departments.name AS dept_name, departments.url AS dept_url
FROM directory
INNER JOIN departments on directory.displayname = departments.name
WHERE directory.displayname = ?
ORDER BY directory.LastName", $queryParams, $queryOptions);

$numofrows = sqlsrv_num_rows($query);

Note that the order you build your array in must match the order in which the ? symbols appear in the query. As you only use one parameter in each query and they are the same, you only need to build one array.

You would then substitute all your mssql functions with sqlsrv functions, for a list of the functions and their usage, see the docs: http://www.php.net/manual/en/ref.sqlsrv.php

Sean Airey
  • 6,352
  • 1
  • 20
  • 38
  • See my edit, I've included links to the documentation as well =] – Sean Airey Nov 15 '12 at 15:37
  • thanks Sean I will give it a try... sometimes I think SQL and PHP will be the death of me. – Inky1231 Nov 15 '12 at 15:43
  • Oh it will be, don't you worry... ;] It might be worth mentioning to whoever is in charge that using an MS SQL database and PHP together isn't exactly a match made in heaven. You'd be better off using MySQL as the database or using .Net for the web application. Obviously I know it's almost never as simple as that but it's something to mention at any rate =] – Sean Airey Nov 15 '12 at 15:49
  • At the bottom of your first piece of code, you've got `mssql_free_result($query)` try changing this for `sqlsrv_free_stmt($query)`. Docs: http://www.php.net/manual/en/function.sqlsrv-free-stmt.php – Sean Airey Nov 15 '12 at 16:06
  • OK I think I have the query working but it's not printing the results and I think it has to do with using `for($i = 0; $i < $numofrows; $i++) { $row = mssql_fetch_array($query); if($i % 2) { print ''; } else { print ''; } ` – Inky1231 Nov 15 '12 at 16:18
  • You'll need to have a look through your code and change any of the mssql functions (e.g. mssql_fetch_array, mssql_num_rows etc.) with the sqlsrv equivalent. So for this one you'll want `$row = sqlsrv_fetch_array($query)` – Sean Airey Nov 15 '12 at 16:20
  • I haven't missed any Mssql btu I still don't get the results printed – Inky1231 Nov 15 '12 at 16:29
  • Could you add the rest of the modified code in to the edit you made so I have a bit more of an idea of what's going on? Thanks =] – Sean Airey Nov 15 '12 at 16:34
  • edited :D I really appreciate your help I have never done the sqlsrv quearies before – Inky1231 Nov 15 '12 at 16:40
  • Ok I've edited my answers, I also noticed that I messed up on the variable names, I said `$queryParams = array($department)` then used `sqlsrv_query($conn, "SQL", $params)` which isn't right, just rename those, add the query options, double check everything and give it a whirl =] – Sean Airey Nov 15 '12 at 16:51
  • Still not working! Argh! so close... obviously the query is running it just isn't showing the results! – Inky1231 Nov 15 '12 at 16:58
  • Can you change the line where you use `@@sqlsrv_has_rows` to `if ($numofrows > 0)` and see if you get your error message? Or just print out the value of `$numofrows`? – Sean Airey Nov 15 '12 at 17:06
  • Did you change your code to `$numofrows = sqlsrv_num_rows($query)`? – Sean Airey Nov 15 '12 at 17:23
  • yes, I have tried it both ways. This may be a dumb question but why does the @ have to be there? – Inky1231 Nov 15 '12 at 17:25
  • The @ doesn't have to be there, try getting rid of it. – Sean Airey Nov 15 '12 at 17:32
  • I have tried and then I get Call to undefined function sqlsrv_num_rows() (same for has rows) – Inky1231 Nov 15 '12 at 17:35
  • If you don't have any joy with that, try moving `$query` to after you've finished with `$query2`. So move the declaration for `$query` to after your while loop with `$query2`. – Sean Airey Nov 15 '12 at 17:37
  • but the while statement is part of an if statement that uses $query... so that wouldn't mess up the if statement. – Inky1231 Nov 15 '12 at 17:41
  • Did you install the sql drivers on your server? I'm assuming you did because you're not getting any errors from the `sqlsrv_query()` functions. – Sean Airey Nov 15 '12 at 17:43
  • I presume they are there I don't have direct access to the server... our server is off site. – Inky1231 Nov 15 '12 at 17:44
  • Ok try changing `$queryOptions = array( "Scrollable" => "buffered" );` to `$queryOptions = array( "Scrollable" => SQLSRV_CURSOR_KEYSET );` and give it a go? – Sean Airey Nov 16 '12 at 09:25
  • still no go. I think it may have to do with the @ in `$numofrows = @sqlsrv_has_rows($query);` but if I take that out I get a call to an undefined function. – Inky1231 Nov 16 '12 at 14:40
  • BTW I asked our server host, and he has no clue about the drivers... (One reason we are changing servers) – Inky1231 Nov 16 '12 at 14:40
  • Can you do a `` in a new file and see if there's a section titled 'sqlsrv'? – Sean Airey Nov 16 '12 at 14:47
  • it says Registered PHP Streams php, file, data, http, ftp, compress.zlib, https, ftps, zip, sqlsrv – Inky1231 Nov 16 '12 at 14:58
  • That's odd.... By the way the @ symbol in front of the functions definitely shouldn't be there, it supresses errors which isn't what we want. Can you check to see if `$query` and `$query2` are null? – Sean Airey Nov 16 '12 at 15:03
  • You can use `isset()` or `is_null()` – Sean Airey Nov 16 '12 at 15:13
  • I did `if (isset($query)) { echo "This query1 is set so I will print."; } if (isset($query2)) { echo "This query2 is set so I will print."; } ` and nothing printed I take that back I put it before the sqlsrv_Num_rows and it printed – Inky1231 Nov 16 '12 at 15:25
  • Can you print the value of `$query` and `$query2` or see if the evaluate to false. I'm thinking if it's set but num_rows isn't returning anything then we have an error happening somewhere in the execution of the SQL. – Sean Airey Nov 16 '12 at 15:31
  • ok I put in `while ($row = sqlsrv_fetch_array($query)) { echo "$row";` }\ to start (test) and I got sqlsrv_fetch_array() expects parameter 1 to be resource, boolean given in C:\Inetpub\wwwroot\DACC\directory\dept.php on line 186 – Inky1231 Nov 16 '12 at 15:42
  • Yeah so there is an error in the sql... Ok so after you do `$query = sqlsrv_query(sql here)` can you put something like: `if ($query === false) { die( print_r(sqlsrv_errors(), true)); }` and see what we get? – Sean Airey Nov 16 '12 at 15:50
  • Array ( [0] => Array ( [0] => IMSSP [SQLSTATE] => IMSSP [1] => -32 [code] => -32 [2] => Option Scrollable is invalid. [message] => Option Scrollable is invalid. ) ) – Inky1231 Nov 16 '12 at 15:51
  • Uuuugh.... I hate the php SQL driver >_< try it with `$queryOptions = array( "Scrollable" => "keyset" )` and `$queryOptions = array( "Scrollable" => "buffered" )`. The thing is `SQLSRV_CURSOR_KEYSET` should evaluate to "buffered" anyway.... – Sean Airey Nov 16 '12 at 16:05
  • I wish I could figure out why sqlsrv_num_rows() is saying undefined function :( – Inky1231 Nov 16 '12 at 16:07
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/19646/discussion-between-inky1231-and-sean) – Inky1231 Nov 16 '12 at 16:10
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/19766/discussion-between-inky1231-and-sean) – Inky1231 Nov 19 '12 at 14:19
  • I'm around all day (another 3 hours ish). I've got chat open so just ping me when you're free =] – Sean Airey Nov 19 '12 at 14:42
  • Hey Sean, thanks for messaging me. I had to let this slide for today, got a deluge of stuff in my to-do bin and today is a holiday week here so we only have three days in the office (Thanksgiving). – Inky1231 Nov 19 '12 at 19:52