Categories
Apache Web Server Linux mail PHP

PHP mail() function not sending email and no error was reported

The problem was that mail() method worked when invoked with php -r "mail('address@domain.tld', 'Subject', 'Message'); but when I tried it via the web server (apache in my case), in a php script, no email was sent and the mail method returned false. On top of this no error was displayed or logged anywhere not even error_get_last function did not return anything and I had display_errors and error_reporting activated and full E_ALL.

After trying all the possible tests that I could imagine I tried to send an email by executing the sendmail command form a php script. When I tried php’s shell_exec with sendmail:

shell_exec('/usr/sbin/sendmail');

and checked apache’s error logs got the error sh: /usr/sbin/sendmail: Permission denied. After I got this error it was obvious that the fix was to change the permissions for /var/qmail/bin/qmail-inject and /var/qmail/bin/sendmail so that apache can execute them.

Then said to myself: Happy developing! and that was it.

Categories
PHP Uncategorized

PHP Unknown error: Collator::__construct(): collator_create: unable to open ICU collator in Unknown on line 0

Full error message that occurred on mac (mavericks) homebrew version of php (php54, php55, php56) with php-intl (php54-intl, php55-intl, php56-intl) with intl.use_exceptions=1 and intl.error_level=E_ALL :

Unknown error: Collator::__construct(): collator_create: unable to open ICU collator in Unknown on line 0
PHP Fatal error: Uncaught exception 'IntlException' with message 'collator_create: unable to open ICU collator' in -:2
Stack trace:
#0 -(2): Collator->__construct('en_US')
#1 {main}
thrown in - on line 2

or without the default ini settings

PHP Fatal error: Call to a member function getLocale() on a non-object in - on line 3

Fatal error: Call to a member function getLocale() on a non-object in – on line 3

or in symfomny2

PHP Fatal error: Call to a member function asort() on null in APP_DIR/vendor/symfony/icu/Symfony/Component/Icu/IcuRegionBundle.php on line 79

After couple of hours I found the error to be inside icu4c library installed via homebrew.

The fix for this error is to reinstall the icu4c library, php and php-intl

brew reinstall icu4c php55 php55-intl

Categories
HTML JavaScript jquery PHP

Weird characters transmitted to and from server through jQuery AJAX call

A simplified example of my app:
I have a HTML form as the output of a PHP script that gets a text from a database and fills an input of that form with it. There I can edit the text that on form submit is sent to a PHP script via a jQuery AJAX call. Through PHP the text is saved in the database and then the saved value is retrieved in PHP and sent in the JSON result of the AJAX call.
The character encoding of the HTML page is ISO-8859-1:

Let’s say the he HTML form looks like this:

<form id="my_form">
<input type="text" id="txtId" name="txt" value="" />
<input type="submit" name="btn" value="save">
</form>

On form submit this AJAX call is made:

$.ajax({
	type: "POST",
	url: "my_script.php",
	data: $("#my_form").serialize(),
	success: function (jsonObj) {
		if(!jsonObj) {
			return;
		}
		if("txt" in jsonObj) {
			$("#txtId").val(jsonObj[txt]);
		}
		return false;
	},
	error: showError,
	dataType: "json"
});

In PHP, after saving the text in the database and retrieving the saved text, I add it to an associative array which I convert into a JSON object displayed as the response of the AJAX call:

$item['txt'] = $value; //$value is the text saved in the database
header("Content-type: application/json");
echo json_encode($item);

At first I submited the form with exactly the text that came from PHP at page load. It looked fine, bun when reloading the page, a weird text filled my form input. I had the text a×b and now I got a×b.
I submitted the form again with text a×b and I studied the AJAX call response with Firebug. In both Console and Net tabs of Firebug, under Post tab of the call everything looked fine, but under Response tab I got “txt”:”a\u00d7b” instead of “txt”:”a×b”.
It looked like the text somwhere on the way back to the form got encoded in a weird manner. The × character is a Windows-1252 encoded character, not an UTF-8 encoded character and I should discover where the encoding of the text changed.
I submitted the correct text again and outputted the text saved in the database without json_encode-ing it:

echo $item['txt'];

In Firebug, in the Response tab of the AJAX call, even though under the Console tab of Firebug the text looked fine, under the Net tab it appeared like this: a×b.

Again I submitted the correct text and outputted the value that came via AJAX:

echo $_POST['txt'];

And again I obtained the correct text under the Console tab and the incorrect one under the Net tab in Firebug, which meant that the encoding broke before the text got to the server.

Then, under Headers tab of the call, I noticed among the Request Headers: Content-Type application/x-www-form-urlencoded; charset=UTF-8 and I thought maybe setting the character encoding of the jQuery.ajax call to ISO-8859-1 instead of UTF-8 would solve my problem:

$.ajax({
	type: "POST",
	url: "my_script.php",
	data: $("#my_form").serialize(),
	contentType: "application/x-www-form-urlencoded;charset=ISO-8859-1",
	success: function (jsonObj) {
		if(!jsonObj) {
			return;
		}
		if("txt" in jsonObj) {
			$("#txtId").val(jsonObj[txt]);
		}
		return false;
	},
	error: showError,
	dataType: "json"
});

But the result remained the same and even more, the Content-Type header did not change either. After lots of thinking and testing, I came to these conclusions:
1. If the data parameter of the jQuery.ajax call is not empty and the type parameter is set to “POST”, the character encoding of the request remains UTF-8 no matter what, so (if I want my encoding to take effect) what I would normaly put in the data parameter I should add to the query string of the url of the AJAX call and not specify or leave the data parameter empty (setting the value of empty string to the data parameter).
2. Explicitly setting the character encoding of the AJAX request to ISO-8859-1 didn’t help at all with my problem.
3. jQuery serialize function `messes up` special characters that are not UTF-8 encoded, because it uses JavaScript function encodeURIComponent which UTF-8-encodes special characters, so make sure to UTF-8-decode the texts in the server script when using jQuery serialize or JavaScript encodeURIComponent function in an AJAX call.

So I left the JavaScript code as it initially was (without specifying the contentType parameter to the jQuery.ajax call) and, in the PHP code, decoded the string before saving it in the database:

$txt = utf8_decode($_POST['txt']);

By now I have the correct text saved in the database, but another problem arises: the text in the response of the AJAX call is null. But why?
PHP function json_encode only works with UTF-8 encoded characters, that’s why. So I should have may own JSON-maker function:

function make_json($item) {
	foreach($item as $key => $value) {
		if(is_array($value)) {
			$arr[] = '"'.$key.'":'.make_json($item[$key]);
		} else {
			$arr[] = '"'.$key.'":"'.str_replace(array("\\", "\""), array("\\\\", "\\\""), $value).'"';
		}
	}
	return '{'.implode(",",$arr)."}";
}

And the code in the PHP script becomes:

header("Content-type: application/json");
echo make_json($item);

But now I get this weird result: a�b (diamond shaped character with question mark inside instead of special characters). This time in the Net tab of Firebug everything looks fine, while the diamond shaped characters appear in the Console tab and in the HTML page.

I solved it by explicitly setting (in PHP) the character encoding of the response of the AJAX call to ISO-8859-1 (thanks to this post):

header("Content-type: application/json; charset=ISO-8859-1");
echo make_json($item);
Categories
JavaScript jquery PHP

Null value of a string variable in the JSON response object of an AJAX call

I have a jQuery AJAX call for a PHP script that retrieves a text value from a database and outputs a JSON object containing it:

$.ajax({
	type: "GET",
	url: "my_script.php",
	success: function (jsonObj) {
		if("txt" in jsonObj) {
			console.log(jsonObj.txt);
		}
	},
	error: function(jXHR, textStatus, errorThrown) {		
		console.log("The info cannot be loaded.", jXHR, textStatus, errorThrown);
	},
	dataType: "json"
});

In PHP, after retrieving the text from the database, I add it to an associative array which I convert into a JSON object displayed as the response of the AJAX call:

$item['txt'] = $value; //$value is the text got from the database
header("Content-type: application/json");
echo json_encode($item);

Even though $value is not null, in the response of the AJAX call txt variable has the null value. Which means that json_encode function fails in the case of my text. As I later discovered, that is because the text I got from the database contained non-UTF-8 encoded characters and in the first parameter of the json_encode function, as PHP manual says, `All string data must be UTF-8 encoded.`
So if you want to handle non-UTF-8 encoded characters through jQuery AJAX calls with JSON data type response, you should make your own JSON encoding function. A basic example would be:

function make_json($item) {
	foreach($item as $key => $value) {
		if(is_array($value)) {
			$arr[] = '"'.$key.'":'.make_json($item[$key]);
		} else {
			$arr[] = '"'.$key.'":"'.str_replace(array("\\", "\""), array("\\\\", "\\\""), $value).'"';
		}
	}
	return '{'.implode(",",$arr)."}";
}

And the code in the PHP script goes like:

header("Content-type: application/json; charset=ISO-8859-1");
echo make_json($item);
Categories
MySQL PHP

PHP isset() function returns FALSE even though the variable is defined

Let’s say we have a table item in a MySQL database, with the primary key iditem and a field code that can be NULL:

CREATE TABLE `item` (
`iditem` int(10) unsigned NOT NULL,
`code` VARCHAR(10) DEFAULT NULL,
PRIMARY KEY (`iditem`),
);

--
-- Dumping data for table `item`
--

INSERT INTO `item` (`iditem`, `code`) VALUES
(1, 'as1435v'),
(2, NULL),
(3, 1, 'YHryt4t90');

In PHP we define a variable $item_code that we initialize with 0 and then we run a query for setting the value of $item_code to the code of the item which has the id 2 in our database:

$item_code = 0;
$query = "SELECT code FROM item WHERE iditem = 2";
$result = mysql_query($conn); //$conn is our database connection
if($result) {
	if($row = mysql_fetch_row($result)) {
		$item_code = $row[0];
	}
}

if(isset($item_code)) {
	echo "item code: ".$item_code;
} else {
	echo "item code is not set";
}

The output will be:
item code is not set

That is because the code is NULL in the database and it is transferred into PHP not as the empty string, but as NULL.
And the name of the isset() function is misleading as it returns FALSE not only when a variable is not defined, but also when a variable has been set to NULL.

Categories
HTML PHP

Strange empty text line appearing inside my page

Usually you see an empty text line and you look at the source and you see nothing there just a space…

That happens often when the files that are outputted are using the encoding UTF8 with signature, instead of using the correct encoding UTF8 without signature.

Categories
How to PHP

How to convert server date and time to the local date and time taking into account daylight saving time

‘Many countries, or even parts of countries, adopt daylight saving time (DST, also known as “Summer Time”) during part of the year. This typically involves advancing clocks by an hour near the start of spring and adjusting back in autumn (“spring” forward, “fall” back).’ (see Wikipedia)

Now I will demonstrate how we can convert a server date and time to the corresponding date and time in another timezone in Europe, taking Romania as example.

‘All countries in Europe except Iceland observe DST, and most change on the same date and time, starting on the last Sunday in March and ending on the last Sunday in October.’
‘In the West European (UTC), Central European (CET, UTC+1), and East European (UTC+2) time zones the change is simultaneous: on both dates the clocks are changed everywhere at 01:00 UTC, i.e. from local times of 01:00/02:00/03:00 to 02:00/03:00/04:00 in March, and vice versa in October.’ (see Wikipedia)

Romania is a country in the Eastern Europe, which falls under the East European Time (EET) also known as UTC+2 time zone and uses Eastern European Summer Time (UTC+3) as a summer daylight saving time.

The next function will be used to find out the offset in hours from UTC (GMT) of a local date and time of Romania or another region that switches between DST and standard time on the same date and time as Romania (is the local date and time in DST or in standard time?)

function local_offset_from_utc($timestamp, $standard_offset)
//$timestamp - the timestamp of the server date and time we want to convert to local date and time
//$standard_offset - the offset from UTC of the local date and time when observing the standard time; in daylight saving time the offset is $standard_offset + 1
{
	$year = gmdate("Y", $timestamp); //get the UTC year of the given date and time
//get the date to 'spring forward'
	$mar_31_utc_ts = gmmktime(0, 0, 0, 4, 0, $year); //the UTC timestamp of March 31, the last day of March, equivalent to gmmktime(0, 0, 0, 3, 31, $year)
	$last_sun_mar = 31 - gmdate("w", $mar_31_utc_ts); //the day of the month under which falls the last Sunday in March
	$spring_ts = gmmktime(1, 0, 0, 3, $last_sun_mar, $year); //the timestamp of the last Sunday in March 01:00 UTC
//get the date to 'fall back'
	$oct_31_utc_ts = gmmktime(0, 0, 0, 11, 0, $year); //the UTC timestamp of October 31, the last day of October, equivalent to gmmktime(0, 0, 0, 10, 31, $year)
	$last_sun_oct = 31 - gmdate("w", $oct_31_utc_ts); //the day of the month under which falls the last Sunday in October
	$fall_ts = gmmktime(1, 0, 0, 10, $last_sun_oct, $year); //the timestamp of the last Sunday in October, 01:00 UTC
	if($timestamp >= $spring_ts && $timestamp < $fall_ts) //daylight saving time
	{
		return $standard_offset + 1;
	}
//standard time
	return $standard_offset;
}

If the server switches between DST and standard time simultaneously with your timezone, you can simply use date("I") to find out if your local date and time is in daylight saving time or standard time:

if(date("I", $timestamp) == 1)
{
	$offset = $standard_offset + 1;
}
else
{
	$offset = $standard_offset;
}

Be careful with that, because a sever don't always switch between DST and standard time at the same hour as the timezone it has set, for example my server switches from DST to standard time at 03:00 UTC+3, which becomes 02:00 UTC+2, when it should go from 04:00 UTC+3 to 03:00 UTC+2). So I better use the function above that works not caring if or when the timezone of the server switches between DST and standard time.

If an offset of a timezone from UTC is negative, then the UTC date and time is greater than the corresponding date and time in the considered timezone; if the offset is positive then the UTC date and time is lower than the corresponding date and time in the considered timezone. If we consider t being the date and time in a given timezone, utc being the corresponding UTC date and time and offset being the offset of the given timezone from UTC, then we have:

t = utc + offset
utc = t - offset

So if we consider t1 being a server date and time and o1 being the offset of the timezone of the server from UTC (in hours) and t2 being the local date and time and o2 being the offset of the timezone of the server from UTC (in hours) we have:

utc = t1 - o1
t2 = utc + o2 = t1 - o1 + o2

In practice we only have a server date and time which we convert to timestamp ts1 based on which we find out the timestamp ts2 when the date and time in the timezone of the server equaled/will equal to the local date and time corresponding to ts1:

ts2 = ts1 - os1 + os2, where os1 = o1 * 60 *60 seconds and os2 = o2 * 60 *60 seconds

E.g. Let's consider the timezone of the server date and time is UTC-5 and Romania is in standard time (has an offset of 2 hours from UTC).

The UTC date and time that corresponds to the given timestamp equals to the server date and time that was/will be 5 hours later than the given timestamp:

ts_aux = ts1 - (-5 * 3600) = ts1 + 5 * 3600

The local date and time of Romania corresponding to the given timestamp equals to the UTC date and time that was/will be 2 hours later than the UTC date and time computed above:

ts2 = ts_aux + 2 * 3600 = ts1 + (5 + 2) * 3600 = ts1 + 7 * 3600

But this is NOT true if the server time and date that equals the needed local date and time falls under DST and the original server date falls under standard time or vice versa, which means that the offsets from UTC of the two server dates are different by 1 hour.

For example, if the server we considered before is in UTC-5 DST and goes back one hour on the first of November at 03:00:00 local server time and we want to see what Romania local date and time corresponds to the server date and time November 1st 01:00:00, then, applying the formula above, we will obtain a timstamp that corresponds to the server date and time November 1st 07:00:00 which should correspond to the local Romania time for the original server time, but the correct Romania date and time being November 1st 08:00:00. That is because, between November 1st 01:00:00 and November 1st 07:00:00, the server goes back one hour so that 03:00:00 DST becomes 02:00:00 standard time and 08:00:00 becomes 07:00:00, while the Romania time does not, Romania switching to DST one week earlier, so the correct formula in this case is:

ts2 = ts1 - os1 + os2 + 3600
ts2 = ts1 + (5 + 2 + 1) * 3600 = ts1 + 8 * 3600

Similarly, if the server switches from standard time to DST between the two dates, the formula becomes:

ts2 = ts1 - os1 + os2 - 3600
ts2 = ts1 + (5 + 2 - 1) * 3600 = ts1 + 6 * 3600

The next function is used to determine what the timestamp was/will be in the timezone of the server when the server date and time equaled/will be equal to the needed local date and time.

function get_timestamp_for_local($date = "", $standard_offset = 2)
{
	if(!empty($date))
	{
		$timestamp = strtotime($date);
	}
	else
	{
		$timestamp = time();
	}
	$os1 = date("Z", $timestamp);
	$os2 = local_offset_from_utc($timestamp, $standard_offset) * 3600;
	$ts = $timestamp - $os1 + $os2;
	//check the offset from UTC of the server date and time that equal the needed local date and time
	$os3 = date("Z", $ts);
	if($os3 == $os1) //the two server dates are both in DST or both in standard time
	{
		return $ts;
	}
	elseif($os3 > $os1) //the server date and time that equal the needed local date and time are in DST and the original server date and time are in standard time
	{
		return $ts - 3600;
	}
 	//the server date and time that equal the needed local date and time are in standard time and the original server date and time are in DST
	return $ts + 3600;
}

And finally we get the needed date and time:

function get_ro_date($date)
{
	return date("d.m.Y H:i:s", get_timestamp_for_local($date));
}

Next l will show how we can convert a server date and time to the corresponding date and time in another timezone in North America, taking the State of Washington as example.

'North America generally follows the same procedure, with each time zone switching at 02:00 LST (local standard time) to 03:00 LDT (local daylight time) on the second Sunday in March, and back from 02:00 LDT to 01:00 LST on the first Sunday in November since 2007.'
In the United States of America, 'the start of DST now occurs on the second Sunday in March and ends on the first Sunday in November.' (see Wikipedia)

The State of Washington falls under the Pacific Time Zone (PT), which is Pacific Standard Time (PST) or UTC-8 when observing standard time and Pacific Daylight Time (PDT) or UTC-7 during daylight saving time.

So we have to change the previous local_offset_from_utc function to find out the offset in hours from UTC (GMT) of a local date and time of Washington:

function local_offset_from_utc2($timestamp, $standard_offset, $spring_forward_hour, $fall_back_hour)
//$timestamp - the timestamp of the server date and time we want to convert to local date and time
//$standard_offset - the offset from UTC of the local date and time when observing the standard time; in daylight saving time the offset is $standard_offset + 1
//$spring_forward_hour - the hour of the local time when switching to DST
//$fall_back_hour - the hour of the local time when switching to standard time
{
//find out the year of the local date and time corresponding to the given server date and time, based on the corresponding UTC date and time
	$year = gmdate("Y", $timestamp); //UTC year of the given server date and time
	if($standard_offset < 0) //local timezone is behind UTC
	{
		//if the given sever date and time corresponds to January the 1st in UTC and the UTC hour is lower than the absolute value of the offset of the local time from UTC, then the corresponding local date and time falls in the year previous to the UTC year
		$month = gmdate("n", $timestamp);
		if($month == 1)
		{
			$day = gmdate("j", $timestamp);
			if($day == 1)
			{
				$hour = gmdate("G", $timestamp);
				if($hour + $standard_offset < 0)
				{
					$year -= 1;
				}
			}
		}
	}
	else //local timezone time is ahead of UTC
	{
		//if the given sever date and time corresponds to December 31 in UTC and the sum of UTC hour and the offset of the local time from UTC is greater than 24, then the corresponding local date and time falls in the year subsequent to the UTC year
		$month = gmdate("n", $timestamp);
		if($month == 12)
		{
			$day = gmdate("j", $timestamp);
			if($day == 31)
			{
				$hour = gmdate("G", $timestamp);
				if($hour + $standard_offset > 24)
				{
					$year += 1;
				}
			}
		}
	}
	//get the date to 'spring forward'
	$mar_1_utc_ts = gmmktime(0, 0, 0, 3, 1, $year); //the timestamp for the UTC time of March the 1st, 00:00:00
	$mar_1_day_of_week = gmdate("w", $mar_1_utc_ts);
	//compute the day of the month under which falls the second Sunday in March
	if($mar_1_day_of_week > 0) //the day of the week of the 1st of March is not Sunday
	{
		$second_sun_mar = 15 - $mar_1_day_of_week;
	}
	else
	{
		$second_sun_mar = 8;
	}
	$spring_local_ts = gmmktime($spring_forward_hour - $standard_offset, 0, 0, 3, $second_sun_mar, $year);
	//get the date to 'fall back'
	$nov_1_utc_ts = gmmktime(0, 0, 0, 11, 1, $year); //the timestamp for the UTC time of November the 1st, 00:00:00
	$nov_1_day_of_week = gmdate("w", $nov_1_utc_ts);
//compute the day of the month under which falls the first Sunday in November
	if($nov_1_day_of_week > 0) //the day of the week of the 1st of November is not Sunday
	{
		$first_sun_nov = 8 - $nov_1_day_of_week;
	}
	else
	{
		$first_sun_nov = 1;
	}
	$fall_local_ts = gmmktime($fall_back_hour - ($standard_offset + 1), 0, 0, 11, $first_sun_nov, $year);
	if($timestamp >= $spring_local_ts && $timestamp < $fall_local_ts) //daylight saving time
	{
		return $standard_offset + 1;
	}
	//standard time
	return $standard_offset;
}

The function get_timestamp_for_local remains the same, only we add 2 more paramters to it which will be needed when calling the function:

function get_timestamp_for_local2($date = "", $standard_offset = -8, $spring_forward_hour = 2, $fall_back_hour = 3)
{
	if(!empty($date))
	{
		$timestamp = strtotime($date);
	}
	else
	{
		$timestamp = time();
	}
	$os1 = date("Z", $timestamp);
	$os2 = local_offset_from_utc2($timestamp, $standard_offset, $spring_forward_hour, $fall_back_hour) * 3600;
	$ts = $timestamp - $os1 + $os2;
	//check the offset from UTC of the server date and time that equal the needed local date and time
	$os3 = date("Z", $ts);
	if($os3 == $os1) //the two dates are both in DST or both in standard time
	{
		return $ts;
	}
	elseif($os3 > $os1) //the server date and time that equal the needed local date and time are in DST and the original server date and time are in standard time
	{
		return $ts - 3600;
	}
	//the server date and time that equal the needed local date and time are in standard time and the original server date and time are in DST
	return $ts + 3600;
}

And now we can find out the date and time in the State of Washington that corresponds to the given server date and time:

function get_wa_date($date)
{
	return date("Y-m-d H:i:s", get_timestamp_for_local2($date));
}
Categories
Apache Web Server PHP

SoftException in Application.cpp:544: Directory “/path/dir” is writeable by group

Full error message: SoftException in Application.cpp:544: Directory “/path/to/directory” is writeable by group

The error apeared in cpanel logs at a hosting company and was related to a directory I created via ftp and where I tried to run some php script. When accessing the script from the web browser i got the error “500 Internal Server Error”

The problem is that Apache 2.0 server doesn’t allow in some cases (i don’t know these cases yet) that the directories created with write access rights set to all unless it’s set by the same unix user as the user running apache process. In order to fix this we need to create the folder from the same user as apache user. To do this we need to create the folder or to change the access rights from php.

The fix is to upload a small php file with the following code:

<?php
chmod("./dir", 0755);
?>

After we set the access right on “dir” to 777 we run the  php script then the error should not appear anymore.

Categories
PHP

When submitting a PHP form, the script does not stop

If you submit a PHP form which passes a large amount of data using the POST method, like a file upload form, it would be a good idea to increase the value of the PHP configuration variable post_max_size (you will find it in the php.ini file) if it seems like the script is running forever. post_max_size should be set to a value larger than the maximum sum of the sizes of the files the script is used to upload.

Categories
Apache Web Server MySQL PHP

Importing a MySQL data file using phpMyAdmin results in incomplete data in MySQL

I tried moving all my databases from MySQL 4.1 to MySQL 5.1 on Windows and since I had some InnoDB tables I could not just copy the data files between MySQL Server versions (from C:\Documents and Settings\All Users\Application Data\MySQL\MySQL 4.1\data\ to  C:\Documents and Settings\All Users\Application Data\MySQL\MySQL 5.1\data\).
So, after I exported the data from the old MySQL Server version I tried importing it to the MySQL 5.1 using phpMyAdmin.
The file to import was 42MB in size, so I had to set some PHP configuration variables (in php.ini file) to greater values:

post_max_size = 64M
upload_max_filesize = 64M

At first it looked like the phpMyAdmin import script entered a loop or something, as it wouldn’t stop even after running for several minutes and, as I was looking into the data files it was producing, no new files appeared. It was like it blocked on a table with a large number of records, which didn’t make any sense. Then I restarted the Apache server and I tried the import all over again. The same thing was happening. I finally decided to let it run for more time and the script finally stopped. But the data imported was incomplete; a part of the records in the large table I thought script blocked on, and every table and database from there on were missing, with no PHP or MySQL error returned.
Then I thought the script needed even more time to run, so I increased the value of the PHP configuration variable max_execution_time, but with the same result.

The solution. It seems that the execution time limit for the import script in phpMyAdmin is defined by the variable $cfg[‘ExecTimeLimit’] in <path_to_phpMyAdmin>/libraries/config.default.php and the value of this variable should be a lot greater than its default value of 300 seconds when importing a great amount of data. In my case it needed about an hour (3600 seconds) to complete. So you have to set this variable depending on the amount of data you are importing.
You might also need to set the MySQL configuration variable max_allowed_packet (in my case, in C:\Program Files\MySQL\MySQL Server 5.1\my.ini) to a greater value, if you have large queries in the data file you want to import, for avoiding MySQL error 2006, ‘mysql server has gone away’.