Articles – Alex Ivaylov – a web developer http://www.alex.bg Alex BG Web Developer Blog Sat, 10 Aug 2024 13:17:17 +0000 en-US hourly 1 https://wordpress.org/?v=4.8.8 Installing imagick on Windows http://www.alex.bg/2017/08/installing-imagick-on-windows/ Wed, 30 Aug 2017 19:24:42 +0000 http://www.alex.bg/?p=885 A few years ago i wrote a post moaning about how difficult it is to install imagick on Centos. Well i have to say that was a breeze compared to installing it on Windows..

As we know it is a PECL extension. On the page we see this “This extension requires ImageMagick version 6.5.3-10+ and PHP 5.4.0+.”.

But what they are not saying there is that you should not use the official windows binaries that you get from imagemagick.org. In fact they are saying the opposite.


When I installed the official binaries together with the PECL extension I got low level crashes of php-cgi.exe. There wasn’t much information on to why.

After that I noticed that on the bottom of the download page of imagemagick that they require Visual C++ 2013 while the php PECL extension and PHP itself require Visual C++ 2015 (VC14). So that explained the crashes.

Just as I was thinking about compiling it myself – I found this great article. The guy has went through the same pain as me.

In that article there is a link to PECL dependencies folder. The link is http://windows.php.net/downloads/PECL/deps# in there there is a different build of the imagick runtime. So I downloaded that and uninstalled the official imagick binaries.

I then added the environmental variables as explained in that article and boom – it started working.

]]>
dynamically manipulate a jQuery Mobile Control Group http://www.alex.bg/2015/05/jquery-mobile-control-group-populate-and-change-dynamically/ Mon, 18 May 2015 18:26:28 +0000 http://www.alex.bg/?p=821 I could not find a working answer to the question How to dynamically populate a control group in jQuery Mobile and programatically change its selected value in the search engines, so I though I would write this quick article.

Now, lets say your HTML looks like this:


<fieldset data-role="controlgroup" data-type="horizontal" id="myContrGrp">
<input name="favFruit" id="favFruit-f1" value="apples" type="radio" />
<label for="favFruit-f1">Apples</label>
<input name="favFruit" id="favFruit-f2" value="bananas" type="radio" />
<label for="favFruit-f2">Bananas</label>
<input name="favFruit" id="favFruit-f3" value="strawberries" type="radio" />
<label for="favFruit-f3">Strawberries</label>
</fieldset>

The first thing I am gonna do with this is I am going to bring in a relation between the VALUE and the ID of the inputs. So something like this is better:


<fieldset data-role="controlgroup" data-type="horizontal" id="myContrGrp">
<input name="favFruit" id="favFruit-apples" value="apples" type="radio" />
<label for="favFruit-apples">Apples</label>
<input name="favFruit" id="favFruit-bananas" value="bananas" type="radio" />
<label for="favFruit-bananas">Bananas</label>
<input name="favFruit" id="favFruit-strawberries" value="strawberries" type="radio" />
<label for="favFruit-strawberries">Strawberries</label>
</fieldset>

Now that there is a link between the ID and the VALUE attributes, we can do something like this:

 


//the value we want to set the control Group to
var favFrt = 'strawberries';
var favFrtSelector = '#favFruit-' + favFrt;
//add the checked="checked" attribute to the appropriate INPUT
$(favFrtSelector).attr('checked', 'checked');
//refresh the control group
$("#myContrGrp").enhanceWithin().controlgroup("refresh");

 

The above concludes how to change the selected option of control group that already exists and has all its HTML pre-set.
If you need to dynamically populate a jQuery mobile group before you change it, follow these steps.

Create an empty fieldset:


<fieldset data-role="controlgroup" data-type="horizontal" id="myContrGrp"></fieldset>

And use something like the following:


//create an array with all your options:
var cgOpts = ['apples', 'bananas', 'strawberries'];
//create your innerHTML container var:
var innerHTML = '';
//iterate through your array:
for (var i=0;i<cgOpts.length;i++)
{
//current fruit is cgOpts[i]
innerHTML += '<input name="favFruit" id="favFruit-'+ cgOpts[i] + '" value="'+ cgOpts[i] + '" type="radio" /><label for="favFruit-'+ cgOpts[i] +'">'+ cgOpts[i] + '</label>';
}
//now that you have your innerHTML - append it to the jQuery Mobile control group like this:
$("#myContrGrp").controlgroup("container").append(innerHTML);
//and refresh the jQuery Mobile control group like this:
$("#myContrGrp").enhanceWithin().controlgroup("refresh");

 

Also, I couldn’t find out how to disable a jQuery mobile control group programatically. The native plugin has a “disable” method as well as a disable option but unfortunately they both don’t work.

What I found did work was adding the disabled=”disabled” attribute to the inputs:


$("#myContrGrp input").attr('disabled', 'disabled');

Remember to refresh after this.


So there you have it. Feel free to copy/paste whatever you like.
Note this was done with jQuery Mobile version 1.4. It might change in future versions.

]]>
Enabling PHP in a single directory http://www.alex.bg/2015/03/enabling-php-in-a-single-directory/ Tue, 10 Mar 2015 18:05:44 +0000 http://www.alex.bg/?p=808 I am writing this because I couldn’t find any information on how to enable PHP for a single directory.

Let’s say we have a website example.com, whose documentRoot is in /var/www/vhosts/example.com. I want PHP disabled for the entire website apart from the directory /myApp.

Let’s say the configuration of the vhost is something like this:


<VirtualHost *:80>
ServerAdmin me@example.com
ServerName example.com

DocumentRoot /var/www/vhosts/example.com

<Directory /var/www/vhost/example.com>
Options -Indexes
AllowOverride All
Order allow,deny
allow from all

#disable PHP:
php_admin_value engine Off
</Directory>
ErrorLog ${APACHE_LOG_DIR}/example.com-error.log
CustomLog ${APACHE_LOG_DIR}/example.com-access.log combined

As you can see we have turned off PHP globally for the whole website.

One thing I found by trail and error is that if you change engine Off to engine On in the above example, PHP will still not work.

That is the case in the current Ubuntu (Debian) Apache 2 with mod_php 5. I dont know if this is a feature or a bug.

If you want to switch on the PHP engine, try 1 instead of On.

This works:

php_admin_value engine 1

So now we need to figure out how to override the flag just for the /myApp directory.

Overriding with <Directory> does not work. What I found is that overriding with <Location> does work. That’s probably because <Location> is called last (after <Directory> and .htaccess).

So here is how to override the PHP engine flag directive for one single directory:


<VirtualHost *:80>
ServerAdmin me@example.com
ServerName example.com

DocumentRoot /var/www/vhosts/example.com

<Directory /var/www/vhost/example.com>
Options -Indexes
AllowOverride None
Order allow,deny
allow from all

#disable PHP:
php_admin_value engine Off
</Directory>
<Location /myApp>
php_admin_value engine 1
</Location>
ErrorLog ${APACHE_LOG_DIR}/example.com-error.log
CustomLog ${APACHE_LOG_DIR}/example.com-access.log combined

I haven’t tried it with .htaccess because I don’t use it any more.

]]>
Upgrading PHP? http://www.alex.bg/2014/01/upgrading-php/ Mon, 27 Jan 2014 21:17:56 +0000 http://www.alex.bg/?p=794 If you think that by upgrading to the latest version of PHP you will be more secure than before you might be wrong. Some security features such as magic quotes GPC and safe mode have been removed as of 5.4.

In HTTP all of the communication coming into a web app from the outside world happens via one of the 3 channels (Get, Post and Cookie). The magic quotes GPC feature automatically escapes the input.

In the newer versions of PHP it has been removed and now it is up to the developer to escape the user input accordingly. Problem is that newbie developers might not know that they have to do that. Other problem is with old legacy code which makes use of magic quotes. Businesses simply can not afford to re-code web applications according to the new standards. Other problem is that the resources available those learning PHP in many cases are out of date and contain code snippets and examples which are potentially vulnerable. That is why it is very important that only seasoned developers who code php the right way are hired for business critical web applications. Of course that will not be the low-tariff developers who cant even speak English.

The other removed feature “Safe Mode” was a handy setting which lets sys admins disable potentially dangerous PHP functionality used by exploits and rootkits (such as the functions which let php run custom code on the system shell (system(), shell_exec(), “, etc). Safe mode also prevents PHP from writing files to the file system. I would actually recommend that safe mode is kept on by default and only disabled if really needed.

The good news is that even though 5.3 is end of life – it still receives critical security updates. So for now you can secretly continue to run 5.3 on your server (which is recommended if you provide shared web hosting and you don’t need the new features). However, we don’t know how long that will continue to be the case. Also remember that there’s the option of running multiple versions of PHP on the same server (as FastCGI) if you are dying for traits or the new password hashing.

]]>
Copying a LAMP web application http://www.alex.bg/2013/06/copying-a-lamp-web-application/ Wed, 12 Jun 2013 23:29:47 +0000 http://www.alex.bg/?p=769 One of the most common things a web professional does is copying a website from one web server to another. Whatever the reason – deploying, debugging, upgrading – it doesn’t matter. A few years ago when I started working with the web – I was using FTP. The more I was digging into the Linux Command Line the less I was using things like FTP until the point I completely stopped using it. You will see how quicker it is doing a copying via SSH compared to downloading all files via FTP and then uploading them again. The 5 main steps you need to take when copying a website are described below:

1. Prepare the new server

If you are using a control panel such as CPanel, Plesk, Kloxo, etc – it is most likely that your environment is automatically prepared when you create the website from the control panel interface because it uses pre-defined templates to create all websites so you don’t need to do any of the preparation here.

Before you can copy a website from server A to server B – you need to ensure that server B is ready. That means that the virtual host is configured properly in Apache, you have a document root folder for the website and Apache is serving it correctly. An easy way to test this is to edit the hosts file on your system and make it point to the IP address of server B. Search google on how to do that. To ensure that Apache is serving the right document root – you could create a test.html file and then try to request it from your browser http://example.com/test.html

Also make sure that server B is matching the system requirements of the web application. Popular CMSes such as WordPress, Joomla, etc have their system requirements on their websites.

Some web systems might require specific Apache options to be set in a specific way and/or specific modules to be enabled – for example if the system uses mod_rewrite – you will need to enable it and if the system also uses .htaccess to specify the rewriting rules – you will need to set the vhost config to have the directory’s AllowOverride to either ‘options’ or ‘all’ (but not ‘none’).

On the PHP side of things – you need to make sure that all the required PHP extensions are installed (that should be specified in the system requirements document).

2. Copy files

Once you are happy that the environment on server B is ready for the website to be copied you can continue.

2.1 The first step before you start copying the website is to suspend it. So if the CMS or the Shopping Cart has an option to close the site – you need to do it now. The reason for that is because you don’t want orders placed (or users registered) on your website between the times DNS has switched to the new server to be lost.
2.2. First you need to change the current directory the directory of your website:

cd /var/www/vhosts/alex.bg/httpdocs/

2.3.Then you need to use the tar utility to create the archive:


tar cfz mywebsite.tar.gz .

When you type the command – it might take some time to create the archive – so be patient.
Once the command has finished – you should see the root@serverA… place to type again.
Make sure that no errors are displayed.
2.4. Open a new SSH window to server B.
2.6. cd to the directory of where the new website will be hosted:

cd /var/www/vhosts/alex.bg/httpdocs/

If you have any files which are not needed by the website in there (like a test.html file) – delete them(using “rm ” command).
2.7. Download the archive from Server A:

wget http://example.com/mywebsite.tar.gz

You should see a file download.
Again – wait for it to finish and make sure no errors are displayed.
2.8. Once the download is complete – extract the files:

tar xf mywebsite.tar.gz

2.9. Once the extract is complete – delete the archive(do this on both servers A and B):

rm mywebsite.tar.gz

Congrats – you have copied all the files from your old server to the new one.

3. Copy database
3.1 The database information is stored into a configuration php file. In most cases it is something like config.php, configuration.php(in Joomla), wp-config.php (in wordpress), etc.
3.2. FTP into your new server and find the config file in there (or use “ls” to view the files).
3.3. After that open the configuration file and look for Database Name, Database User and Database Password variables (constants in WordPress).
3.4 On server A – login to your database manager (phpmyadmin) via the control panel or via the PMA url if you have installed it yourself (using the username/password from above step).
3.5 On the top left click on “Databases”, then click the database name.
3.6. Click “Export” on the top
3.7. Leave it as “quick” and click the “export” button
3.8. A .sql file should download – save the file to your computer
3.9. Logout of phpMyAdmin on Server A and login to phpMyAdmin on server B (preferably using a root account)
3.10. Again, click on “databases” on the top left
3.11. In the “Create new database” section enter the name of the database exactly as the way you had it in 3.3.
3.12. After your database has been created – click on it’s name
3.13. Click import
3.14. Click “browse” and find the .sql file you just downloaded from the other server
3.15. Click the “Import” button and wait for the file to import. Your browser might look like frozen but wait for it (it might take hours depending on your network speed and size of the .sql file).
After it completes – you should see a list of all the tables in the database on the left.
Again – make sure no errors are displayed.
3.16. After the import is complete – create a new user for this database
3.17. Click “users” (or “Privileges” in the old phpMyAdmin) on the top of the screen
3.18. Click add new
3.19. Now you could either specify the old user/password you have from step 3.3. or enter a completely different user/password combination. Make sure that host is set as “localhost” and you have not assigned any global server rights to the user. I would recommend using a new user/pass combination because it is always good to change credentials.
3.20. If you created a new user/password – update the config file with them, save it and then upload it to the server B. If you used the old user/pass – skip this step.
3.21 Go into the “users” section of the database again and go into the “edit user” screen for the user you just created.
3.22 From the drop down with database names find the one you just created and submit the form
3.23. Assign only the privileges needed for the web system to work (if you are no sure – you could have a look at Server A to see what privileges the user has to the database there).

4. Test

At this stage your old website should be working on your new server.

Make sure the hosts file is pointing to the new server and load the website. If you closed the web system – open it again. Do not open the website on Server A – only the one on server B.

Test everything – if you see any errors – search Google.

5. Change DNS
Once you are happy that your website works on the new server as intended – change the DNS of the domain name. Look for A records. Where you see the IP address of Server A, change it to the IP of Server B (note this might effect services different than web such as Email, so make sure those are set up on the new server properly too).

After DNS switches your visitors should be served by the new server. If you are intending to close your old server’s hosting account make sure you cancel it properly (using the system of the host provider) because some hosts do auto-renew and charge your card without any notice (bad practice in my opinion).

]]>
June 2013 already? http://www.alex.bg/2013/06/june-already/ Wed, 12 Jun 2013 21:58:57 +0000 http://www.alex.bg/?p=754 Is it June already? Time flies when you are having fun! haha… Last time I wrote here was in January, so I guess the plan to start writing here more often failed. The truth is that I have been busy with soo many different things.

On the personal side of things – it’s all the same (partying, travelling, socialising, living life to the full and enjoying the small things). I must admit – the weather in Scotland has been lovely for the last few weeks. I think that Europe and Scotland exchanged – while EU gets all the rain – we got the sunshine in Scotland 🙂

On the technology side of things I have been digging deep into the mobile side of the web (building HTML5/CSS3/jQueryMobile web apps in Cordova) as well as trying to build the perfect MVC PHP framework to use for my own projects (I might release it under the GNU/GPL one day).

So far I have a very good database class which has enough functionality in its methods to almost replace writing SQL queries. The DB class uses the PHP PDO interface and it is meant to be the parent of the model class of the MVC framework I am building. That means that the model will be inheriting (extending) the DB class which will give standard $this->blah access to its methods. For example to get the result of this query

$query = 'SELECT `name`, `surname` FROM `people` WHERE `id`=\'' . $id . '\';';

as an array you would just do this in my class:


$peopleArray = $this->listFiltered($fields=array('name','surname'), $dbTable='people', filterData=array(array('field'=>'id','value'=$id, type='equals')));

So with one line you get the result you need without having to go through the standard PDO procedures (instance class, separate dynamic data, run query, etc). Similar methods are available for all the standard SQL statements (SELECT/UPDATE/DELETE). As you saw above it also supports complex operations such as specifying WHERE clauses(with all the operators), LIMIT parameters and JOIN instructions. I also have a few other classes like the user management/authentication class, methods for simple front-end database table records management (something like phpMyAdmin but simplified) + a few other classes.

There are hundreds of PHP frameworks that offer similar functionality but the truth is that they are all too limited for what I need. The technology and data I work with is spread from a lot of different programs on different platforms and different devices which have their own APIs and data formats with their own constrains and requirements (that’s the simplest way to put it without going into technical details). That’s why I am thinking that my framework is something unique.

]]>
The Modulus operator, The Ternary operator and FizzBuzz in PHP http://www.alex.bg/2013/01/the-modulus-operator/ http://www.alex.bg/2013/01/the-modulus-operator/#respond Sun, 06 Jan 2013 01:21:33 +0000 http://www.alex.bg/?p=705 Happy new year! I’ve disabled my Facebook so I think I will start writing here more often..

Anyway, I wanted to talk about the Modulus operator % in PHP (which is very similar to most other programming languages).

From the PHP docs, we know that it returns the “Remainder of $a divided by $b“. But what does that mean?

It means that it will return the difference between $a and the first number which can be cleanly divided by $b if you start counting down from $a.

Here are a few examples

(3 % 3) = 0 (0 because 3 itself can be  divided by 3 cleanly)
(4 % 3) = 1 (1 because if we start counting down, 3 is the first number that can be divided by 3 which leaves us a reminer of 1)
(5 % 3) = 2
(6 % 3) = 0
(7 % 3) = 1
(8 % 3) = 2
(9 % 3) = 0

To create your own examples like above, you could use this loop code:
<?php
for ($i=1; $i<100; $i++)
{
$res = ($i % 3);
echo "<br />({$i} % 3) = {$res}";
}
?>

Usage examples

Here is an example where we calculate how many apples we can buy and what change will be left:
<?php
//the money we have:
$myMoney = 134;

//the price of an apple:
$applePrice = 3;

//the change which will be left after we buy all the apples:
$change = ( $myMoney % $applePrice);

//the cost of the apples:
$applesCost = ( $myMoney - $change );

//the number of apples we can buy:
$apples = $applesCost / $applePrice;

echo "We have &pound;{$myMoney} which will be enough to buy {$apples} apples if the price of an apple is &pound;{$applePrice}. The total cost will be &pound;{$applesCost} that means we will have &pound;{$change} change left.";

?>

The above example will result in:
We have £134 which will be enough to buy 44 apples if the price of an apple is £3. The total cost will be £132 that means we will have £2 change left.

Highlighting every second row
The most common usage of the modulus operator I have seen so far in PHP is identifying every n-th element (every second element, every third element, etc).
As you have noticed from the examples above, the reminder is 0, if a number can cleanly be divided.

So here is an example of how we can highlight every second result
<?php
for ($i=1;$i<100;$i++)
{
echo '<span';
if ( !($i % 2) ) { echo ' style="color: red;"'; }
echo '>' . $i . '</span>';
}
?>

The above will output:
123456789
Pay attention to the IF statement line “if ( !($i % 2) ) “. Basically we are saying “if $i % 2 returns false, then echo the inline style which adds the red colour CSS property”. As you might have seen above, the operator does not return bool (true or false) values but it returns integers. However, PHP is a loose-type language and it converts zeros to False and all other numbers to True if it finds a context where an integer has to be used as bool.
For that reason, there is nothing wrong with the IF line, however if we want to reduce the work that PHP has to do by eliminating the conversion, we could compare it vs 0 by saying “if ( ($i % 2) == 0 ) “, which does exactly the same but is better because there are no conversions in place and the expression is valid bool. An even better example will be “if ( ($i % 2) === 0 ) ” which again does the same comparison but it is also checking if both numbers are of the integer data type.

Now, since all that we are doing is ECHO, we could also use the ternary operator (?) (also known as a conditional operator) which you will find is very popular for cases like this:
<?php
for ($i=1;$i<100;$i++)
{
echo '<span';
echo ( ($i % 2) == 0 ) ? ' style="color: red;"' : '';
echo '>' . $i . '</span>';
}
?>

The ? operator does exactly the same as the IF statement in the previous example.

If you prefer one-liners, here is how you could do the same echo:
<?php
for ($i=1;$i<100;$i++)
{
echo '<span' . ( ( ($i % 2) == 0 ) ? ' style="color: red;"' : '' ) . '>' . $i . '</span>';
}
?>

So all we did there was wrap the ternary expression in brackets () and embed it within the string we are echo-ing.

FizzBuzz exercise

One of most popular job interview tasks is the FizzBuzz classic which makes good use of the modulus operator:

“Write a program that prints the numbers from 1 to 100. But for multiples of three print “Fizz” instead of the number and for the multiples of five print “Buzz”. For numbers which are multiples of both three and five print “FizzBuzz”.”

If you go for a job interview, it is likely that you will be asked to do this. If you have understood everything I have said in this article so far and you have basic PHP experience, you will not have any problems of doing this on your own.

Here is my example:

<?php
for ($i=1;$i<=100;$i++)
{
if ( ($i % 3) === 0) { echo 'Fizz'; }
if (($i % 5) === 0) { echo 'Buzz'; }
if ( ( ( $i % 5 ) != 0 ) && ( ($i % 3) != 0 ) ) { echo $i; }
echo '<br />';
}
?>

And here is the same example with ternary operators:

<?php
for ($i=1;$i<=100;$i++)
{
echo ( ($i % 3) === 0) ? 'Fizz' : '';
echo (($i % 5) === 0) ? 'Buzz' : '';
echo ( ( ( $i % 5 ) != 0 ) && ( ($i % 3) != 0 ) ) ? $i : '';
echo '<br />';
}

We could also unite the ternary expressions (with brackets like in the above example). Here is the first two echo-es united:

<?php
for ($i=1;$i<=100;$i++)
{
echo ( ( ($i % 3) === 0) ? 'Fizz' : '' ) . ( (($i % 5) === 0) ? 'Buzz' : '' );
echo ( ( ( $i % 5 ) != 0 ) && ( ($i % 3) != 0 ) ) ? $i : '';
echo '<br />';
}
?>

And here is all the echo-es united into one:


<?php
for ($i=1;$i<=100;$i++)
{
echo ( ( ( ( $i % 5 ) != 0 ) && ( ($i % 3) != 0 ) ) ? $i : ( ( ( ($i % 3) === 0) ? 'Fizz' : '' ) . ( (($i % 5) === 0) ? 'Buzz' : '' ) ) ) . '<br />';
}
?>

Yes, it’s possible to unite all the echo-es into one, but I wouldn’t reccomend it for the simple reason that it will make a programmer cry blood if they have to read it and follow it.
In my opinion, the example with the four echo-es is the best becasue it is easy to follow.

Well, that’s all i could think of about the Modulus operator – it’s bed time for me 🙂

]]>
http://www.alex.bg/2013/01/the-modulus-operator/feed/ 0
From MySQL to SQL server for PHP devs http://www.alex.bg/2012/11/from-mysql-to-sql-server-for-php-devs/ http://www.alex.bg/2012/11/from-mysql-to-sql-server-for-php-devs/#respond Fri, 16 Nov 2012 15:44:03 +0000 http://www.alex.bg/?p=693 As you know, I have been a LAMP developer for years. I simply love all the things that make LAMP amazing – Apache, PHP, MySQL and Linux. Last year some fellow developers were trying to convince me to move away from Apache and switch to nginx but they failed. I am that type of developer who always try to use the most used technologies. The reason for that is because they are usually the most stable.

Recently, I have been asked to develop a PHP application that runs on Windows Server’s IIS and uses Microsoft SQL server as a RDMS. As you might have expected this has been a new experience for me and it has been rather bad.

The reason why I am doing this post is to try and help other developer with PHP/MySQL background switch better. So lets get started!

1. Installing

Best way to install PHP on IIS7 is to use the Microsoft Platform Installer. It provides a Microsoft-style wizard with next-next steps. After you complete the install, restart IIS (World Wide Web publishing service). The wizard also installs a third party PHP manager for IIS Management Console, which is basically a graphic front end for the PHP.ini file’s variables which we are used to editing ourselves in Nano 🙂

After you install it, it will come with a sqlsrv driver which lets you connect to MS SQL server. Now this is the first thing that got me confused. Last time I looked into PHP extensions for SQL server, it was called “mssql”. I was also looking on the PDO installation page at php.net and it was called “mssql” there too. Later on I found out that Microsoft have made their own PHP driver for SQL server and they have called it sqlsrv. Now sqlsrv is much better than mssql (something like mysql and mysqli).

2. PDO
Now the next thing that will get you confused is creating a new PDO object. It seems that Microsoft have made their own syntax which is different from the standard syntax we have in PHP. Have a look at the MSDN page for PDO as you might have noticed the syntax is a little different:

MySQL:

$DBH = new PDO(“mysql:host=$host;dbname=$dbname”, $user, $pass);

MS SqlSrv:

$DBH = new new PDO(“sqlsrv:Server=$host;Database=$dbname”, $user, $pass);

So in the DSN it’s not “host”, but it’s called “Server” and it’s not “dbname” but it’s “Database”. Microsoft inventing their own things again without following the standard (why am I not surprised?).

 

3. SQL Syntax
Now the  next thing you might notice is the different syntax from MySQL. For example, in MySQL we surround the column names (attributes) with grave accents (`) but in MSSQL we suround them with square brackets ([]). In addition to that there is a “dbo” before every table. Have a look at the queries below to see the difference:

MySQL:

SELECT `field1`, `field2`, `field3` FROM `tablename`;

MS SqlSrv:

SELECT [field1], [field2], [field3] FROM [dbo].[tablename];

 

4. Order By with DISTINCT

In MySQL we can order by anything we like and we don’t have to select it even if we use DISTINCT. In MS SQL, if you are using DISTINCT, you have to select the field which you are ordering by. Jeff from sqlteam has more about this here.

In addition to that you can not have it inside sub-queries. That’s very stupid. What if I don’t want the RDMS to return the field I am ordering by? Has anyone at Microsoft thought of that scenario?

 

5. Limit

There is no such thing as LIMIT in MSSQL. A possible work around I thought of was a sub-query together with MSSQL’s row_number(). See below:

MySQL:

SELECT `id`, `name` FROM `table` LIMIT 0,50;

MS SqlSrv:

SELECT [sq].[id], [sq].[name] FROM (SELECT ROW_NUMBER() OVER (ORDER BY [t].[id]) AS “rn” [t].[id] AS “id”, [t].[name] AS “name” FROM [dbo].[table] t) sq WHERE [sq].[rn] BETWEEN 1 AND 50;

I dont need to say how lame that is.

UDPATE: In addition to this, you cannot use “ORDER BY” inside subqueries. That makes it impossible to select the data you might want.

UPDATE 2: A possible solution is to store the IDs of the rows you want inside variables and do an “WHERE [id] BETWEEN @minId AND @maxId”.

6. Import/Export

I think I discovered a bug in the Import/Export data wizard for SQL server where the columns were not mapping to fields as they were supposed to when importing from CSV. Have a look at the comment I made at the Oscar Valles post.

7. WHERE statement

You know how we are used to mixing whatever we like in the WHERE clause in MySQL? Well, you cant do that in MSSQL..

SQL query ( SELECT [id] FROM [dbo].[table] WHERE [field1] = ? AND [field2] = ? ) failed. SQLSRV PDO execution caught an exception with message “SQLSTATE[42000]: [Microsoft][SQL Server Native Client 11.0][SQL Server]The data types text and nvarchar are incompatible in the equal to operator.”

The most stupid thing
I cant decide which one is the most stupid and badly designed feature because there are so many to choose from..
However my favourite one is the design of the SQL Server Management Studio (SSMS). For example, if you want to edit the values in a table (from a GUI) you need to right click on the table and select “Edit top 200 rows”. After that you get a window that lets you edit the values. First stupid thing here is what happens if I want to edit something which is not in the top 200 rows? I can’t.. The second one is why am I getting all the 200 if I only want to edit 1 of them? And the third one is the instant commitment. As soon as you click out of something it gets saved into the database. You don’t have the option to “Cancel” those changes or to commit (save) them if you like. It all happens as soon as you click out of something – chances of making a mistake and messing up your database are higher than ever. Another hard thing to do in SSMS is browsing records – you can only select the top 1000 and not having the LIMIT statement makes it even harder to go to the next set of rows. Perhaps Microsoft should learn from PhpMyAdmin’s navigation where you have pagination for the records and each page is 30 rows. After that you have an edit option for each individual row where you have the option to cancel or save. You would think that in the 21st century the management software of an RDMS should let you change any record you like without having to issue an UPDATE query yourself.

And talking of UPDATE queries – if we say you have a column which has a length of 5 chars and then you try and update the value for that column in one of the rows with a simple update query:

udpate [dbo].[users]
SET [email] = ‘myLongEmailUserName@myLongDomainName.com’

The error you will get is not something stating that the data is too long but it will be something suggesting you have a syntax error:

Line 1: Incorrect syntax near ‘.’.

Even after you change the design of the table, you will still get this. You need to open a “new query” window and re-run it there.

Well that’s it for now. I will be adding to this post as I go.

]]>
http://www.alex.bg/2012/11/from-mysql-to-sql-server-for-php-devs/feed/ 0
about passwords and web security in general http://www.alex.bg/2011/06/about-security-on-the-web/ http://www.alex.bg/2011/06/about-security-on-the-web/#respond Thu, 30 Jun 2011 12:57:00 +0000 http://www.alex.bg/?p=621 The topic about passwords never gets old. They are the unique string which a user has to enter into a web site in order for the system of that site to know who the user is.. But you already know that of course.

In the beginning passwords could be anything from just a single letter to 20 chars. Then password polices got a little stricter and most of the websites made a requirement for at least 4 characters, then the limit was lifted to 6 characters. Now in the last few years some websites have lifted the limit to 8 characters and others have also added additional security requirements such as having both upper and lower case characters and numbers in the password.

That’s all good and it is going in the right direction, however, users are not happy with that at all. A lot of users are so frustrated, when they try to register on a website and they are asked to change their password and add numbers to it, that they just don’t bother doing it. That way, the website owner looses visitors/customers and as a result looses money and website reputation.

Back in the day passwords could be just anything because there were not so many and even if accounts were hacked it wasn’t that critical – there wasn’t that many e-commerce websites and other things involving money. The only thing that people were using which could be hacked were emails but, usually there was just spam in them which wasn’t valuable.

Nowadays, passwords can’t be just words. The web is world wide. This includes all those dodgy places such (as Nigera) which means that all these bad people from across the world (some of you may call them “hackers” but “crackers” would be more suitable in my opinion) could make an attempt to login as you and access your money or other valuable information. The attempt is more likely to be successful if your password was just a word. If your password was matching the new polices (having both lower/uppercase/number/etc) it is less likely that the Nigerians would get access to your money.

The modern crackers are not sitting down and trying each word that comes on their mind manually. It’s easier for them if they write a program, which tries thousands of different words automatically until it gets the right one. Having these thousands of crackers, trying thousands of words it is most likely that you will get hacked if you used something like “health” as your password.

To give you an idea of what the strength of the passwords nowadays, we will use analyzes from the recently hacked sony accounts:

An analysis by security researcher Troy Hunt revealed that two-thirds of users with accounts at both Sony and Gawker used the same password on both sites... Half the password sample from the Sony hack used only one character type and only one in a hundred passwords used a non-alphanumeric character, much the same as revealed by the earlier Gawker hack. Only 4 per cent of these passwords had three or more character types.

read the complete analyzes here

So this means that the crackers are currently way ahead in front of users. If one of those users with a weak password becomes the target of an experienced cracker, it is just a matter of time for the cracker to get illegal access.

If something like that happens, legally it is entirely the user’s fault for using that weak password and the website cant be held liable for any damages. The users don’t know that, they think that if something happens it’s the website’s fault not theirs. They want their data, money, etc to be secure but they also want to use “1234” as password at the same time. That is what the problem is.
Possible solutions to this problem are universal cross-webstie online identities such as openID. However, they are still not bullet proof.

Another problem is that even the complex passwords will not be that secure in the near future with the crackers improving and using faster and faster software (some of which is run on graphics cards) with more and more words in their databases.

In my opinion the whole username/password login model must change in the future because it will soon be useless. I dont know what we should use instead. We cant relay on low level limits (such as limiting a user to an ip) because we live in the mobile days, where the mobile phones change their ip address on every cell they register.

I cant think of a better identification mechanism. Can you?

]]>
http://www.alex.bg/2011/06/about-security-on-the-web/feed/ 0
Web based IDE http://www.alex.bg/2010/12/web-based-ide/ http://www.alex.bg/2010/12/web-based-ide/#respond Sun, 05 Dec 2010 20:31:36 +0000 http://uk.alex.bg/?p=546 If you are like me and you travel all the time, from one place to another and you use different computers all the time you probably miss most of your software all the time. Well, at least one problem could be solved with this web based Integrated Development Environment (IDE) by Mozilla:

http://mozillalabs.com/skywriter/

I’ve not had the chance to fully test it yet, but will extend this article when I have time.

]]>
http://www.alex.bg/2010/12/web-based-ide/feed/ 0