How to install PHP 5.4, Apache 2.4, MySQL 5.6.19 and phpMyAdmin 4.2 on Windows 7

In this tutorial I am going to show you how to install PHP 5.4.30, Apache 2.4.9, MySQL 5.6.19 and phpMyAdmin 4.2.2 on a Windows 7 machine. This is a standard set of software that is required for PHP development.

When you read this tutorial it is quite likely that there are newer versions available of the software I used. In most cases if you download the latest version it shouldn’t change the installation procedure…but you can never know, so if you run into problems, read up on possible solutions or try to use the versions listed here and see if it helps.

Installing Apache

You can download the latest 2.4 Apache for Windows from this site: http://www.apachelounge.com/download/. You will also need the VC11 Visual C++ Redistributable for Visual Studio 2012. You can download it from here: http://www.microsoft.com/en-us/download/details.aspx?id=30679.

First install the  VC11 Visual C++ Redistributable for Visual Studio 2012, then download and extract the Apache web server. The extracted folder contains a folder named Apache24, copy this where you want Apache to reside. I’ll have it under the following path: C:/Software/Apache24.

Next, we need to register Apache as a service. In your command line (open it as an Administrator) navigate to the bin directory of your Apache installation. In my case it is: C:/Software/Apache24/bin, and issue the following command:

httpd -k install

The -k option tell Apache to start the service immediately after installing it. If the installation is successful, you will recieve an output similar to the following:

Installing the Apache2.4 service
The Apache2.4 service is successfully installed.
Testing httpd.conf....
Errors reported here must be corrected before the service can be started.
httpd: Syntax error on line 37 of C:/Software/Apache24/conf/httpd.conf: ServerRoot must be a valid directory

As you can see it notifies you that the ServerRoot must be a valid directory. This is because by default the configuration specifies c:/Apache24 as the Apache installation directory. Open the httpd.conf file in your conf directory and replace all occurrences of c:/Apache24 with the path to your actual installation directory.

Run the services.msc command to see if Apache is really installed. You should see Apache2.4 in the list of services. Apache service installed

 

Remember that we recieved an error when we installed it so it couldn’t start then. Right click on the Apache service and start it.

Type localhost or 127.0.0.1 in your browser and you should see a blank page with an “It works!” message. This HTML page is located in the htdocs directory. It is served by the Apache web server, so it works correctly. Although, currently it is only capable of serving static content.

Installing PHP

You can download PHP for Windows from this site: http://windows.php.net/download/. Choose the latest 5.4 thread safe version that is available. At the time of writing the latest 5.4 release is 5.4.30. I know that 5.5 has been around for a long time, but I have come across a couple of hosting providers where the highest available version is 5.4 so for compatibility reasons I am sticking with that.

Download PHP, extract it, and move it to the desired location. I moved PHP to the C:/Software/php-5.4.30 directory. In the root of this directory find the php.ini-development file and rename it to php.ini, this will contain the configuration of PHP.

The next thing to do is to enable Apache the serving of PHP pages. For this, add the following lines to the end of your httpd.conf file:

#Configure the PHP module
LoadModule php5_module "C:/Software/php-5.4.30/php5apache2_4.dll"
AddHandler application/x-httpd-php .php

#Configure the path to php.ini
PHPIniDir "C:/Software/php-5.4.30"

Change the paths according to the directory structure you have. Apache needs a module to support PHP pages, this is why we load php5apache2_4.dll, it is in the root of your PHP installation directory.

If you don’t find the dll, then you probably donwloaded the not thread safe version of PHP.

While we are at it, we  configure Apache to use index.html and index.php as welcome pages. This means that if you point your browser to a directory that contains one of these files, Apache will automatically display it rather then showing the directory structure. This requires the following config:

DirectoryIndex index.html index.php

To try out if PHP works, rename the index.html located in the htdocs directory to index.php and place some PHP code in it. Then open localhost in your browser. If all went well, you should see the result of you interpreted PHP code.

I used the following php code:

<html>
<body>
    <?php phpinfo(); ?>
</body>
</html>

And this is what I see:

Installing MySQL

Download the MySQL Community Server. You can download the latest version (at the time of writing 5.6.19) from this site: http://dev.mysql.com/downloads/mysql/.

Installing MySQL is a pretty straightforward process, just download the Windows installer and follow the steps. After the installation is completed the MySQL server instance configuration wizard opens.

Choose the Detailed configuration, but just accept most of the default settings. The only changes you should make is to set the character encoding to utf8 and provide a password.

At the end of the wizard, the MySQL service will be registered and started automatically.

Checking the MySQL connection

To check the connection I suggest you to install  MySQL Workbench. This is a great tool for administering your databases and designing your database schemas.

To test your MySQL server, create a new connection:

  • Hostname: 127.0.0.1
  • Port: 3306
  • Username: root

Then click on Test Connection and type in the password you provided during installation.

mysql_connection

mysql_connection_working

 

phpMyAdmin

Download the latest version from here: http://www.phpmyadmin.net/home_page/downloads.php. You can check on the download page if it is compatible with the PHP version you are using.

Extract the downloaded archive, rename the folder to phpmyadmin and copy it to the htdocs directory. Type localhost/phpmyadmin/setup/index.php in your browser. You should see the following error message:

Fatal error: Call to undefined function mb_detect_encoding() in 
C:\Software\Apache24\htdocs\phpmyadmin\libraries\php-gettext\gettext.inc on line 177

To fix this open php.ini and perform the following changes:

  • Set your extension_dir to the correct path according to your PHP installation. In my case it is: extension_dir = “C:/Software/php-5.4.30/ext”
  • Enable the php_mbstring.dll extension by uncommenting it.

If you restart your Apache, your should now be able to load the page. However, there are still two errors displayed:

Bzip2 Bzip2 compression and decompression requires functions (bzopen, bzcompress) which are unavailable on this system. 
Cannot load or save configuration Please create web server writable folder config in phpMyAdmin top level directory as described in documentation. 
Otherwise you will be only able to download or display it.

To solve the first one, enable the php_bz2.dll extension in your php.ini and restart Apache. For the second one, create a directory called “config” in your phpmyadmin folder. If you refresh your browser, the errors are gone. Leave everything on default and open localhost/phpmyadmin. There you can see another error 🙂

The mysqli|mysql extension is missing.

There is a quick fix for this also. Enable the php_mysql.dll and php_mysqli.dll extensions and restart Apache. Now phpmyadmin should work correctly.

This completes our setup.

Conclusion

As you can see, installing these software seperately involves a few gotchas, but leaves you with complete control over your development environment. You can easily swich any of the components to newer versions at any time.

If you would rather like a quicker installation, then check out WAMP or XAMPP. They are ready made packages containing all of the software we have just installed but you will have much less control over the individual components.

Where Maven puts files during build

If you build a project with Maven, you can notice that it creates a target folder, and copies the resource files, the compiled source files, the test resource files and the compiled test source files into specific directories. For example the target/classes directory will contain the compiled source files and the resource files. The questions that could arise are:

  • How Maven know that it needs to create the directories with these names?
  • How does it know where to find the source files to compile?
  • How does it know where are the resource files?

They must be configured somewhere, otherwise Maven wouldn’t know what are the names of these directories. The important thing to know here is that contents of pom.xml files can be inherited. These default settings that we get are  inherited from another pom xml file called the Super POM, from which every pom gets it’s default settings.

The directories mentioned above are defined in the Super POM similar to this:

<build>
    <directory>target</directory>
    <outputDirectory>target/classes</outputDirectory>
    <finalName>${artifactId}-${version}</finalName>
    <testOutputDirectory>target/test-classes</testOutputDirectory>
    <sourceDirectory>src/main/java</sourceDirectory>
    <scriptSourceDirectory>src/main/scripts</scriptSourceDirectory>
    <testSourceDirectory>src/test/java</testSourceDirectory>
    <resources>
      <resource>
        <directory>src/main/resources</directory>
      </resource>
    </resources>
    <testResources>
      <testResource>
        <directory>src/test/resources</directory>
      </testResource>
    </testResources>
  </build>
</sxh>

Note the directories that are created can be different if you overwrite these configuration options in your project’s pom.xml file.

Download source

You can download the source files used in this project here.

If  you build this project using the mvn clean install command, you can check out the created target folder and the directories inside it.

 

 

Using Spring Type Conversion

Spring type conversion make it possible to create converters which can convert between different types of objects. These converters can be registered to a conversion service. This service can be used to convert a given object to a given type.

To create a converter you have to write a class which implements the following interface.

public interface Converter<S, T> {
   T convert(S source);
}

Built in converters

Several converter implementations are provided in the core.convert.support package as a convenience. These include converters from Strings to Numbers and other common types. Consider StringToInteger as an example Converter implementation:

final class StringToInteger implements Converter<String, Integer> {
    public Integer convert(String source) {
        return Integer.valueOf(source);
    }
}

Creating custom converters

To create a custom converter you have to write a class similar to the above, where you describe how to convert from one type to another.

First let’s create two types. We will perform the conversion between them.

ConsumerEntity contains the data of a consumer queried from the database.

public class ConsumerEntity {
   private int id;
   private String firstName;
   private String lastName;
   private String zipCode;
   private String city;
   private String street;

   // Getters and setters omitted for brevity
}

ConsumerBo on the other hand contains the fields that we would like to display about the consumer. It is called a BO (Business Object) because it contains data important to the business. In this case it means data we would like to display about a consumer.

public class ConsumerBo {
    private int id;
    private String name;
    private String address;

    // Getters and setters omitted for brevity
}

Now, let’s create a class called ConsumerConverter which will perform the conversion. Remember, this class must implement org.springframework.core.convert.support.Converter.

import org.springframework.core.convert.converter.Converter;
import conversion.example.ConsumerBo;
import conversion.example.ConsumerEntity;

public class ConsumerConverter implements Converter<ConsumerEntity, ConsumerBo>{
    public ConsumerBo convert(ConsumerEntity source) {
        ConsumerBo result = new ConsumerBo();
        result.setId(source.getId());
        result.setName(source.getFirstName() + " " + source.getLastName());
        result.setAddress(source.getZipCode() + ", " + source.getCity() + ", " + source.getStreet());
        return result;
    }
}

Register the custom converter

To use our custom converters, we have to register them in the application context xml using a bean definition like the following:

<bean id="conversionService" class="org.springframework.context.support.ConversionServiceFactoryBean">
    <property name="converters">
        <list>
            <bean class="conversion.example.converter.ConsumerConverter"/>
        </list>
    </property>
</bean>

Invoking the conversion service

Below there is an examaple of using the conversion service we created. The service itself is autowired by Spring into the controller. This autowired object can be used to explicitly perform the conversion from one class to another.

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.convert.ConversionService;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.servlet.ModelAndView;

import conversion.example.ConsumerBo;
import conversion.example.ConsumerEntity;

@Controller
public class HomeController {

    @Autowired
    ConversionService conversionService;

    @RequestMapping("home")
    public ModelAndView displayUser() {
        ModelAndView result = new ModelAndView("user");

        ConsumerEntity consumerEntity = new ConsumerEntity();
        consumerEntity.setId(1);
        consumerEntity.setFirstName("John");
        consumerEntity.setLastName("Doe");
        consumerEntity.setCity("Tokio");
        consumerEntity.setZipCode("2000");
        consumerEntity.setStreet("Oykayong 20.");

        ConsumerBo consumerBo = conversionService.convert(consumerEntity, ConsumerBo.class);

        result.addObject("user", consumerBo);
        return result;
    }
}

Download source

You can download the source code of a working example here.

References

How to add syntax highlighting to Blogger

Blogger has a lot of great widgets built in to include various funcionality in your blog, but syntax highlighting is not one of them. Fortunately it is fairly easy to add this capability, you just have to do some customizing as described below.

Add custom CSS and JavaScript includes to the template

As the first step you have to include the CSS and JavaScript code into the template you are currently using. On you blog’s admin panel select Template and click Edit HTML.

template_edit_html_2014_01_19

In the code search for the </head> tag and just before that insert the following code.

<!-- Syntax Highlighter START -->
<link href='http://alexgorbatchev.com/pub/sh/current/styles/shCore.css' rel='stylesheet' type='text/css'/>
<link href='http://alexgorbatchev.com/pub/sh/current/styles/shThemeDefault.css' rel='stylesheet' type='text/css'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shCore.js' type='text/javascript'/>

<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushAS3.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushBash.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushColdFusion.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCSharp.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCpp.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushCss.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushDelphi.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushDiff.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushErlang.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushGroovy.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJScript.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJava.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushJavaFX.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPerl.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPhp.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPlain.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPowerShell.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushPython.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushRuby.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushScala.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushSql.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushVb.js' type='text/javascript'/>
<script src='http://alexgorbatchev.com/pub/sh/current/scripts/shBrushXml.js' type='text/javascript'/>

<script language='javascript' type='text/javascript'>
SyntaxHighlighter.config.bloggerMode = true;
SyntaxHighlighter.all();
</script>
<!-- Syntax Highlighter END -->

Add code to your post

Go to the post editor screen and switch to HTML view.

post_edit_screen_2014_01_19

In the HTML view paste your code and surround it with a <pre> tag, and set the highlighting mode in the class attribute of the tag. Here is an example of that.

<pre class="brush:java">
public static void main(String[] args) {
    System.out.println("Hello World!");
}

This produces the following output:

public static void main(String[] args) {
    System.out.println("Hello World!");
}

Keep in mind that if you have angle brackets in your code then you have to escape them (with this tool for example), otherwise it will be interpreted as part of the HTML.

Getting rid of unnecessary brushes

The code I pasted above contains a lot of brushes, which make it possible to use a lot of different highlighting methods. However if you know for sure that you will never need some of them, then you can just delete the unnecessary ones saving some HTTP requests.

Use other themes

There are a few CSS themes available on the author’s website if you would like to change the appearance of the code blocks.

Warning

With certain Blogger themes this method may not work.

Pictures uploaded to Blogger post become grey

Recently I was writing my first ever blog post and wanted to include some screenshots in it. I uploaded the screenshots in Blogger’s editor and I noticed that something was off with them. It became even more apparent when I published the post and viewed it on the live site.

The images had too much grey in them. My first though was that I messed them up when converting to a smaller size, but quickly ruled out this possibility when I saw that the images on my local drive had no traces of the unwanted greyness.

The first image is the original, the second is after it was uploaded to blogger.

example_image_white_2014_01_19

example_image_grey_2014_01_19

It turned out that Google has some “smart” algorithms which try to enhance to quality of your uploaded images. And of course it is enabled by default. I don’t know how they perform on regular pictures taken for example on a holiday, but they definitely do bad for screenshots with a lot of white in them.

The following images illustrate step-by-step how to turn this feature off:

google_plus_profile_button_2014_01_19

google_plus_settings_button_2014_01_19

google_plus_auto_enhance_auto_awsome_2014_01_19