View RSS Feed

sonofsanta

Installing a PHP/MySQL Development Server for students on Windows Server 2012 - Part1

Rate this Entry
by , 26th April 2013 at 04:28 PM (13404 Views)
This is going to get lengthy. In the interests of keeping it under control, I'm going to assume you know what you're doing to a certain extent.

With all the curriculum changes in ICT/Computer Science, our head of ICT wants to start teaching more PHP, which sounds like a grand plan to me (that's where my degree is, so of course I know that PHP is the best of all scripting languages).

I have no real experience in setting up Linux servers for the usual LAMP paradigm, so I thought I'd give it a go on Windows. Turns out, it's pretty damned easy.

I've done all this on a standalone server because I don't want errant scripts and queries dragging down my main intranet server. We had a spare physical server lying around anyway so we figured we may as well get some use out of it while it still ran.

I'm going to go through all the way, from installing Windows to installing MySQL. You don't need the MySQL bit if you don't want; you can still do cleverness with forms with PHP alone (and that's our intention here for KS4).

Setting up Windows Server 2012 (in brief)
Install a server as normal.

Setting up Windows Server 2012 (not quite so brief)
Install Server 2012 Standard. 2008R2 works as well but you may as well use 2012 now it's out. 2008R2 will have variations from this guide.
Do all your updates, set your IP, add to domain, etc. etc.
I always have an OS drive [C:] and a data drive [D:]. I'll be setting user files up on D:, it's probably a good idea to do this too.

Little things to remember:
  • In Firewall > Advanced Settings > Inbound & Outbound, allow File and Printer Sharing Echo Request ICMPv4, otherwise you will go insane chasing non-existent network problems when you can't ping your new server.
  • Allow RDP Connections. You can do this from Server Manager > Local Server.
  • If you want one user to be able to have multiple sessions (e.g. Administrator), open regedit, browse to [HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Contro l\Terminal Server] and set "fSingleSessionPerUser" to 0


From the Server Manager dashboard click Add Roles.
With Role-based or feature-based installation selected, click Next. Click Next again.
Scroll down and select Web Server. Keep clicking next until you get to Role Services. Select CGI inside Application Development. Install all this.

In Server Manager, go to IIS, right click on your server name and choose IIS Manager
Expand your server, expand sites, right click on Default Web Site, go to Manage Websites and choose Advanced Settings
Change the Physical Path to where you will store your user files (e.g. D:\inetpub\wwwroot)

Download the Microsoft Web Platform Installer and install it.

Installing PHP 5.4.9
Once the WPI has installed it should open. Search for PHP, find PHP 5.4.9 in the list. Click the Add button. Click the Install button.

Browse to the PHP install directory (e.g. C:\Program Files (x86)\PHP\5.4) and rename php.ini to php.ini.old. Then find php.ini-development, make a copy and rename the copy php.ini. That will change a load of settings to those more suitable to a development environment, including, importantly, outputting error messages to the browser instead of only to the error file.

Download the WinCache Extension for PHP (it improves PHP performance)
Run that download and extract the files somewhere convenient. There's a readme in there, but in brief:
  • copy php_wincache.dll into C:\Program Files (x86)\PHP\v5.4\ext
  • open C:\Program Files (x86)\PHP\v5.4\php.ini; at the end of the file, add this to the end of the file: extension=php_wincache.dll

(no spaces on that last line, despite what the readme file shows)

Create a new text file called info.php in your web-site root. Inside, write
<?php phpinfo(); ?>
and save it. Open a web browser on the server and go to localhost/info.php; you should see a long page full of fun information about your PHP install, thus proving it's working. There should also be a section headed wincache (about 80% down, just search for it); if so, wincache is installed. If not, read that readme, I didn't have any problems

If you want to send mail from PHP scripts using mail(), open up C:\Program Files (x86)\PHP\v5.4\php.ini, search for 'SMTP' and put your mail server address on the relevant line. You can also provide a default from-address with sendmail_from a few lines down.

Granting students access
Firstly, a note on our username structure: we work on year of entry, e.g. our current year 7 are 2012 accounts. The username is in the format jsmith12. You will need to adapt this section to suit your own usernames and domain.

Share your website root folder (e.g. D:\inetpub\wwwroot) with everyone (full access). Change your NTFS permissions down to Everyone: Read
Create some subfolders for your year groups (e.g. I have 2012, 2011, 2010...)

Create a group in AD for your PHP users to belong to. Domain Local works fine, Security group.

Get a CSV file of usernames for students who need access. The header should be "username", such that the file, when opened, just looks like
Code:
username
jsmith12
jbloggs12
...
Save this CSV file on one of your domain controllers as C:\Scripts\PHPUsers.csv (you can save it wherever you please, tbh, but that's the location my script assumes)
Drop the following file into that same folder, deleting the .txt extension: SetFolderPermission.ps1.txt (as sourced here; a useful little script, that one)

Save this script in the same place, deleting the .txt extension, then get ready to amend it: php.ps1.txt
You will need to:
  • alter the dsquery user to reflect your OU structure
  • change the dsmod group to reflect the group name you are using, and your OU structure
  • change the domain prefix for the $user variable
  • alter the switch case to suit your username pattern
  • alter the $path variable to reflect the share name of your web server

After you've changed the script, you can run it in Powershell and it will - from that original CSV - add the user to the group, create a folder for them in the correct year group subfolder, and grant them full permission on that folder.

We're going to map each user's just-created folder to a drive letter; we'll use the same letter 7 times over and use Item Level Targeting to map correctly (we need to do this because of the year group subfolders)
In Active Directory, create a new GPO on your users or students OU (as appropriate). On the scope tab, under Security Filtering, delete Domain Users and add your PHP User group as created earlier, such that the GPO only applies to the relevant users.
Under User Config > Preferences > Windows Settings > Drive Maps, create a New Mapped Drive.
Action = Update
Location = \\server\share\yearGroup\%username% (e.g. \\phpserver\wwwroot\2012\%username%)
Label = PHP Server, or whatever you want to use.
Use = any spare letter
On the common tab, click the Targeting button
New Item > Security Group
Add your year group Security Group (e.g. all Year 7s here are members of Students - Year 2012).
(If you don't use security groups, you can filter by OU, do a wildcard comparison on the username - presumably you will have some way of distinguishing between users)
Once you've set one drive map up like this, right-click on it, copy, then paste X times and tweak the copies till you have all the relevant year groups covered.
You might also choose to map the root of your share for your IT teachers, so they can easily access everyone's files. Don't forget to modify your NTFS permissions to reflect this.

End Result (PHP Development)
At logon, your students will have a new mapped drive [e.g. P:]. They can drop a PHP file directly into this drive, work on it with Dreamweaver, Notepad, whatever.
They can then access it in a web browser through http://server/year/username/file.php
For example, a Year 7 girl Jodie Smith creates helloWorld.php in her P: drive. As soon as she has saved the file in her editor, she can go to http://php/2012/jsmith12/helloWorld.php and see the results. No need to FTP or compile or anything - as soon as changes are saved in code, they are reflected on a page refresh. Brilliant!

Next time
In Part 2 - How to get MySQL running, administer it, and let kids have access to it, both from a database admin point of view and in their PHP code.

Updated 28th November 2014 at 11:05 AM by sonofsanta

Categories
Uncategorized

Comments

  1. NikChillin's Avatar
    Brilliant!!!!!!
    When will the next bit be available please?
  2. sonofsanta's Avatar
    Quote Originally Posted by NikChillin
    Brilliant!!!!!!
    When will the next bit be available please?
    Around the end of April just gone it's here: Installing a PHP/MySQL Development Server for students on Windows Server 2012 - Part2 - Blogs - EduGeek.net
  3. fiza's Avatar
    excellent - this is exactly what we need!!!

    I am working through your guide. I am at the part of mapping the drive and I get an error and am unable to map the drive.
    In Event Viewer I get :

    The client-side extension caught the unhandled exception '0xC0000005' inside: 'threadEntry : client main' See trace file for more details.

    I googled this and found a hot fix KB976399 but it only applies pre win7 SP1.

    Did you come across this?
  4. NikChillin's Avatar
    Quote Originally Posted by fiza
    excellent - this is exactly what we need!!!

    I am working through your guide. I am at the part of mapping the drive and I get an error and am unable to map the drive.
    In Event Viewer I get :

    The client-side extension caught the unhandled exception '0xC0000005' inside: 'threadEntry : client main' See trace file for more details.

    I googled this and found a hot fix KB976399 but it only applies pre win7 SP1.

    Did you come across this?
    Hi Fiza, I didn't do the mapped drive part as the teacher wanted ftp access.
  5. sonofsanta's Avatar
    Didn't flag up for me so I won't be any help I'd double check permissions (NTFS and sharing) as a first call but other than that, you're going to have to rely on Google I'm afraid.

    Hope it's proving useful otherwise, anyway!
  6. fiza's Avatar
    Got it working!!
    My VM client didn't have SP1 Doh!!!!

    works a treat.
  7. fiza's Avatar
    @sonofsanta - Been working great since I set it up. Now a couple of teachers want to have access same as the students do. They want to be able to demonstrate how to do things so want it set up exactly as it is for the students. Whats the easiest way to do this? Their usernames don't follow the same format as the students.
  8. sonofsanta's Avatar
    For teachers, I map the K drive to the root of the wwwroot folder, so they can access all the student work as well. Similar to how the kids are mapped, I've added the K drive mapping to the usual staff drive mapping GPO and used Item Level Targeting to check membership of the PHP Users group. If it meets the criteria, map the root of wwwroot, where I've manually added NTFS permissions for the relevant department (i.e. curriculum IT).

    Means they can create their own folders & structure to their heart's content, as well as look at any code they need to when assisting kids, and means I can drop example code in there for the stealing.

    I suppose you can easily enough tweak it so it maps to wwwroot/staff/%username% if they want it working exactly the same, depends on how much confidence they have in the kids' ability to understand "your K drive is here, look, I can show you"

    Glad it's working well for you, it ain't half been a lot easier here than faffing around with FTP!
  9. fiza's Avatar
    @sonofsanta - Hopefully you can help me with a query from the teacher. I know nothing of PHP so would welcome some help.
    Students are using php to write to a csv file in their area. They create the php file and then browse to it in IE. It should look for a csv file, open it and write to it. If it doesn't exist it should get created. Below is the file. it doesn't seem to work, doesn't create the file and if I manually create the file it doesn't amend it either. We get the "success" at the end but it hasn't done anything.

    Code:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Untitled Document</title>
    </head>
    <?php
    $list = array (
    	'aaa', 'bbb', 'ccc', 'dddd'
    );
    
    $fp = fopen("http:\\phpsvr\08\08brooksa\file.csv", "a");
    
    foreach ($list as $fields) {
        fputcsv($fp, $fields);
    }
    
    fclose($fp);
    
    
    echo 'success';
    ?>
    <body>
    </body>
    </html>
    Updated 27th November 2014 at 04:20 PM by fiza
  10. sonofsanta's Avatar
    The reason you're seeing "success" is because that's not dependent on anything i.e. it's not part of any conditional statement. All that shows is that PHP has reached that point in the script, regardless of what's happened before. I guess you're not seeing the errors it's throwing though, in which case there's something useful you can do to make PHP development much easier for everyone

    On your server, browse to the PHP install directory (e.g. C:\Program Files (x86)\PHP\5.4) and rename php.ini to php.ini.old. Then find php.ini-development, make a copy and rename the copy php.ini. That will change a load of settings to those more suitable to a development environment, including, importantly, outputting error messages to the browser instead of only to the error file. If you made any changes to php.ini before (e.g. the mail server, as above) make them again here. Restart w3svc to reload PHP using these new settings.

    I'll put that in the main post above, because damn if it ain't handy.

    Once you've done that, loading the PHP page should show you what's actually going wrong, and on what line of the PHP script. I got two errors out, from line 12 and line 15 (which was repeated due to the loop).

    Line 12 was permissions; I added Full Control permissions for IUSR on the local server (i.e. search the server, not your directory when you go to Add Permissions) to the wwwroot folder containing everyone's work folder.

    The line 15 error was an error in the way fputcsv() was being used - that function actually wants an array as input, and does all the CSV formatting itself, so there's no need to use the loop.

    Amending the script to fix that problem, and shuffling it to use an IF loop to check if the file could be opened/created before declaring success or otherwise, the script ends up as the fairly similar:
    Code:
    <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
    <html xmlns="http://www.w3.org/1999/xhtml">
    <head>
    <meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
    <title>Untitled Document</title>
    </head>
    <?php
    $list = array (
        "aaa", "bbb", "ccc", "ddd"
    );
    
    if($fp = fopen("file.csv", "a"))
    {
        fputcsv($fp, $list);
        fclose($fp);
        echo("Great Success!");
    } else {
        echo("Could not open/create file!");
    }
    
    ?>
    <body>
    </body>
    </html>
    If you still have problems with permissions, use Process Monitor on the server to capture events as you refresh the page, then filter your results to show only Process Name = php-cgi.exe, and look for any ACCESS DENIED results. Open the Event Properties and look for the Impersonating: at the end of the Event tab. I suspect yours will be NT AUTHORITY\IUSR same as mine, though.

    HTH!

Trackbacks

Total Trackbacks 0
Trackback URL: