Artificial Intelligence Development

You can now run Machine Learning on EventStoreDB through MindsDB

I have recently stumbled upon MindsDB on Product Hunt. The way it works is by first connecting to a data source, creating a machine learning model, training and then running a prediction. All this is done in a SQL-like query.

So I decided to add one more database integration, my favourite and the best state transition database, EventStoreDB. At the moment my Pull Request is still in review at (update: it’s merged!).

What this means is that you will need to checkout that branch and build it locally if you would like to use the EventStoreDB integration. Thankfully, this is not hard to do.

How to build MindsDB locally for development?

In a few steps:

  1. Make sure you are using Python 3.9
  2. Checkout the branch that you want locally
  3. Go to the folder create a virtual env (python -m venv .)
  4. Activate the environment, for example: on Linux: source <venv>/bin/activate or on Windows C:\> <venv>\Scripts\activate.bat
  5. python develop
  6. python -m mindsdb (A web UI should pop up)
  7. Or you can open it in PyCharm (configure it to use the same interpreter and venv). You can be able to just run it.

How to use the EventStoreDB Integration?

Access the Web UI at if it has not yet opened.

MindsDB UI

Before creating a connection, you should make sure your EventStoreDB is running with EnableAtomPubOverHTTP=True, RunProjections=All and to enable the $streams projection. This is required to allow MindsDB to get all the available tables i.e. streams. Make sure that $streams stream has at least one available stream.

The integration treats EventStoreDB streams as tables and every JSON Event’s data key as column. Events with nested JSON are flattened with underscore as the separator.

Once you have done that, you can run a query to create a connection to your EventStoreDB. You could use the following for an insecure ESDB node.

WITH ENGINE = "eventstoredb",
    "host": "localhost",
    "port": 2113,
    "tls": False

Or if you would like to connect to a secure node

WITH ENGINE = "eventstoredb",
  "user": "admin",
  "password": "changeit",
  "tls": True,

If this is successful you should then see on the left a drop down to display all the tables (streams).

How to run Machine Learning on your EventStoreDB data?

Now that we have access to EventStoreDB’s data, we can create a model and train it on that data. For the sake of this example we will use a stream named house_price_changes and events with the following data format:

"EUR": int,
"year": int

Add a few dummy data, if you are having trouble doing that you can follow this article: Using F# and EventStoreDB’s gRPC client is easy

Once you have at least 10 events, you can then create a model.

You should be able to see it in your MindsDB editor as follows:

You can get a quick statistical analysis on your data by clicking on the data insights button.

For example this shows that we have a gap in your data and that we are missing data for the year 2006.

Creating a simple ML model in MindsDB

The simplest model is to just do regression on the data and to predict the EUR field based on the year field.

CREATE MODEL mindsdb.home_price_model
FROM house_price
  (SELECT * FROM house_price.home_price_model)
USING engine = 'lightwood',
      tag = 'house price model';

This will cause MindsDB to start training the model. This can take a while so if you would like to check the status of the training you can run a select command on the model name. For example:

FROM mindsdb.models
WHERE name='home_price_model';

Or you can click on the drop down on the left showing all models.

Making prediction with MindsDB

Once training is successful, you can start making predictions. You do that by making a SELECT query against the model you just created. For example:

FROM mindsdb.home_price_model
WHERE year=2023;

Here we are using the data that we have (2000 to 2010) available to predict the price of a house in the year 2023. This will produce a result in EUR (your prediction).

This is the simplest version of Machine Learning. There are more interesting(and complicated) things that can you run and predict at

Have fun! 😀


Visualize your EventStoreDB data with Polyglot Notebooks

In this post we look into:

  1. Connecting to ESDB
  2. Writing events
  3. Reading the events
  4. Deserializing the events
  5. Sharing the events with Javascript code
  6. Visualizing the events with d3js.

You can check the code at:

How to create a Polyglot Notebook project in VS Code

Step 1: Install Visual Studio Code

Step 2: Install the extension and .NET 7 SDK

Step 3: From Visual Studio code: Click Help->Show All Commands->Polyglot Notebook create default notebook as shown below:

Then choose Choose .ipyb and then F#.

You are now ready to write interactive code in multiple languages as we will see further. By the way Visual Studio Code has likely installed .NET interactive in background.

How to specify different languages in Polyglot Notebooks

You can either write #!fsharp at the start of the cell or you can click and choose bottom right as show in the screenshot. Upon clicking on it you will find all the Notebook Kernels available to run your cells.

For example:

How do you install NuGet Libraries in Polyglot Notebooks?

Next we need to import our EventStore gRPC Client libaries like we did in Using F# and EventStoreDB’s gRPC client is easy

To do that we need to add a special #r and then details about our NuGet package. So for us the following:

#r "nuget: EventStore.Client.Grpc, 23.0.0"
#r "nuget: EventStore.Client.Grpc.Streams, 23.0.0"

If you are not sure what to write, the web page of the NuGet package will help you. Click on the Script & Interactive tab:

If you then click on the Play button of the cell you will see that VS Code will try to install the packages:

Once this is done, click the +Code button to create a new cell.

Write Events To ESDB with FSharp

Let’s start by writing events. We already covered that in Using F# and EventStoreDB’s gRPC client is easy. We need to create a list of events and send them to ESDB. We can do that as follows:

open EventStore.Client
open System.Collections.Generic

let client = EventStoreClientSettings.Create "esdb://"
             |> EventStoreClient

let streamName = "house_price_changes"
let eventsList = List.init 10 (fun index ->
        ReadOnlyMemory<byte>(Encoding.UTF8.GetBytes("{\"USD\":"+ string(Random().Next(1000,2000))+", \"year\":"+string(2000+index)+"}"))
client.AppendToStreamAsync(streamName, StreamState.Any, eventsList).Wait() //assuming stream doesn't exist

We are creating JSON events, you can use System.Text.Json to serialize types if you want. Later we will cover how to Deserialize your JSON events in FSharp.

Adding D3.js code

Create a new cell, this time put the kernel as Javascript or add #!javascript at the start. In the code, we will create a bar plot. You can do more complex visualizations but the underlying principles are the same.

configuredRequire = (require.config({
    paths: {
        d3: '[email protected]/dist/d3.min'
}) || require);

var caller = null;
plot = function (data) {
    configuredRequire(['d3'], d3 => {
        // Call d3 here.
        const margin = {top: 30, right: 30, bottom: 70, left: 60},
        width = 512 - margin.left - margin.right,
        height = 512 - - margin.bottom;

        // append the svg object to the body of the page
        const svg ="#my_dataviz")
            .attr("width", width + margin.left + margin.right)
            .attr("height", height + + margin.bottom)
            .attr("transform", `translate(${margin.left},${})`);

        // X axis
        const x = d3.scaleBand()
        .range([ 0, width ])
        .domain( { return d.year; }).reverse()) //because I was reading backwards

        .attr("transform", `translate(0, ${height})`)
            .attr("transform", "translate(-10,0)rotate(-45)")
            .style("text-anchor", "end");

        // Add Y axis
        const y = d3.scaleLinear()
        .domain([0, 2000])
        .range([ height, 0]);

        .attr("x", function(d) { return x(d.year); })
        .attr("y", function(d) { return y(d.USD); })
        .attr("width", x.bandwidth())
        .attr("height", function(d) { return height - y(d.USD); })
        .attr("fill", "#69b3a2")

Here we have imported d3.js from an external source, we are using the year as x-axis and USD as y-axis. We have mapped our domains based on the values in our data to the different positions on the x-axis and height of rectangles (our ranges). D3.js is mainly about mapping data to domains to ranges to shapes in SVG.

Note: If you want to add transitions you can check examples here: At the time of writing “true” streaming is not supported, you have to use js intervals and call d3 to update your graphs if you want them to change live with data connected with ESDB.

Reading our data and Deserializing JSON to a FSharp type

open System.Collections.Generic
open FSharp.Control
open System.Text.Json //to deserialize JSON event data to house_price_change type

type house_price_change = { USD : int ; year : int }
let eventToPair (resolvedEvent: ResolvedEvent) = //convert resolved event json data to house_price_change
    let JSONEventString = Encoding.UTF8.GetString(resolvedEvent.OriginalEvent.Data.ToArray())
    JsonSerializer.Deserialize<house_price_change> JSONEventString

let priceChanges  = List<house_price_change>() //we will append data that is read from ESDB and share this list with Javascript

    |> TaskSeq.iter (fun event -> (priceChanges.Add (eventToPair <| event)))
    |> Async.AwaitTask
    |> Async.RunSynchronously

Here we create a type house_price_change type house_price_change = { USD : int ; year : int } and we use System.Text.Json to deserialize our event’s JSON data to that type. This happens in our handler in ReadStreamAsync when we call our eventToPair function. In retrospect this would have better been called eventToHousePriceChanges 😅

We could have also used the serialize function to do the reverse when we were appending events.

Anyway, everyone is an expert in retrospect!

Sharing our variable to Javascript and plotting our data

<div id="my_dataviz"></div>

#!share --from fsharp priceChanges
console.log(priceChanges); //we receive the variable in a nice format

Finally, we create a cell with first html code to create a div which will hold our graph. Then we tell the cell to start handling javascript code with #!javascript.

More interesting here, we tell the cell take our priceChanges variables which is a list holding a specific type. This works surprisingly well as you will see from the console output:


Then we pass that variable to out plot function defined before which will plot our price changes. This should generate a graph like the one below:

That’s it, you can continue to build on top of this. If you add other kernels like Python you could add even add machine learning to your notebooks (have not tried).

If you are confused about any part of this post please feel free to comment!


Using F# and EventStoreDB’s gRPC client is easy

The most popular client for EventStoreDB is the dotnet client, so naturally, this makes the library easy to use in F# as well. The first part is creating a project.

Disclaimer #1: I am still new to FSharp/F# so it is likely that the code is not as elegant as you would expect.

Disclaimer 2: This uses F# 6

dotnet new console -lang "F#" -o project_folder_name

Next we need to import the following libraries

dotnet add package EventStore.Client.Grpc --version 22.0.0
dotnet add package EventStore.Client.Grpc --version 22.0.0

You should be ready to use the library. Let’s get started with connecting to an EventStoreDB instance.

Import the library with:

open EventStore.Client

Then connect to the instance by providing a connection string.

let client = EventStoreClientSettings.Create "esdb://"
             |> EventStoreClient

The code above initialises an EventStoreDB client with a connection string telling the telling to connect to a single EventStoreDB instance running in insecure mode on localhost listening on the default HTTP port 2113.

After that you have to create a list of events to write. You can do that as follows:

let streamName = "sample_stream"
let eventData = EventData(
                    ReadOnlyMemory<byte>(Encoding.UTF8.GetBytes("{\"some\":\"json data here\"}"))
let eventsList  = List<EventData>()

Feel free to wrap this in style with a record and functions to make it sexy. Basically we are create one event and adding it to a System.Collections.Generic List. You will likely need to import this.

After that writing events can be done as follows:

    let result = client.ConditionalAppendToStreamAsync(streamName, StreamState.Any, eventsList).Result
    match result.Status with
    | ConditionalWriteStatus.Succeeded -> printfn "Events were written!"
    | ConditionalWriteStatus.StreamDeleted -> printfn $"Didn't expect stream to be deleted"
    | ConditionalWriteStatus.VersionMismatch -> printfn $"You should read"
    | _ -> printfn $"unknown outcome! {result.Status}"
    | _ as e -> printfn$"{e.Message}"

We are trying to write with ConditionalAppendToStreamAsync, synchronously waiting for the result and matching the status with different outcomes. At the moment we have the versioning to Any, you might want to read about what that means and idempotency in EventStoreDB:

Reading the event written is a bit trickier, you have to use TaskSeq to handle the IAsyncEnumerable returned. So you will first need to import

dotnet add package FSharp.Control.TaskSeq --version 0.3.0

You can then do a read backwards, of 1 event (1L means one Long) starting from the end of the stream.

    |> TaskSeq.iter (fun event -> printfn$"
                      data: {Encoding.UTF8.GetString(event.OriginalEvent.Data.ToArray())}")
    |> ignore
//probably need to wait here

I hope this has helped you get started with FSharp/F# and EventStoreDB. In this short post we have seen how to write and read events. There are more exciting things that you can do with EventStoreDB, so let me know if you would like to see more posts like this!


How to remove blocked or pop-ups

The reason for me writing this is the following attack (An intrusion attempt by was blocked) from blocked by Norton:

From the above it looks like is trying to access a host.docker.internal at port 5986. This is assuming that I am running docker and that may be I am running a vulnerable version, which it can take advantage of. Norton has thankfully detected it.

At first I thought that the attack was coming from online but after checking the error in detail I noticed that it was coming from Google Chrome.exe.

Turns out that survey smiles is a browser hijacker. It gets installed in your system and that causes the program to run in background but I think through an extension as we will see below.

I tried to:

  1. Do a full scan (failed my patience)
  2. Do a system restore (failed)
  3. Uninstall Chrome (also failed)

Then I realised that with both a system restore and uninstalling chrome I had kept my browsing data and that it was most likely related to something in chrome.

I then reviewed all the extensions that I had installed (even those that were installed from over a year ago). Turns out that the issue was originating from the “SetupVPN – Lifetime Free VPN” extension for me. Be careful, it will redirect you to an unsafe website when you remove it.

There might be other affected extensions based on feedback that I have seen online. So my recommended approach is going to be to clean up all the Chrome extensions and install them one by one to check.

Best of luck, this was an annoying one to remove!


How to fix Benchmark was built without optimization enabled (most probably a DEBUG configuration). Please, build it in RELEASE. in Fsharp / F#

Chances are you trying to BenchmarkDotNet to test your Fsharp/F# code. The easiest way to run F# code with BenchmarkDotNet is to build your project in Release mode.

If you really want to debug to the benchmark this is not the right article. This article is about building your FSharp project for Release.

We explore two ways to do this in this article:

1. Using Rider IDE

By default Rider will build the project in Debug mode. So you will need to go to Build->Change Solution Configuration… Then you will need to choose “Release | Any CPU”. Now you can build and run your code and it should work.

2. Using terminal / command line

You will need to add an additional parameter to your dotnet build as follows:

 dotnet build -c Release

The dash c Release tells dotnet to build it for Release. Alternatively you can also use dotnet run as follows:

dotnet run --project YourFSharpProject -c Release

This should be enough to get you going. There are plenty of other articles about how to write BenchmarkDotNet in FSharp so we will not cover it here. Have fun!


Five ways to benchmark your Python code

1. timeit module

timeit module: This is a built-in Python module that provides a simple way to measure the execution time of small bits of Python code. You can use the timeit.timeit() function to time the execution of a single line of code or multiple lines wrapped in a function.

For example:

import timeit

def some_function():
    # code to be timed
    x = [i**2 for i in range(10000)]

print("Time taken by the function:", timeit.timeit(some_function, number=1000), "seconds")

Sure, here’s a simple example that demonstrates how to use the timeit module to measure the execution time of a piece of code:

Copy code
import timeit

def some_function():
# code to be timed
x = [i**2 for i in range(10000)]

print(“Time taken by the function:”, timeit.timeit(some_function, number=1000), “seconds”)
In this example, the timeit.timeit() function is used to measure the execution time of the some_function function. The number parameter is used to specify how many times the function should be run. In this case, it’s set to 1000, so the function will be executed 1000 times and the average time will be returned. The output of the code will look like this:

Time taken by the function: 0.17904642399999998 seconds

You can also use timeit to time a single line of code. For example:

import timeit

print("Time taken by the code:", timeit.timeit('x = [i**2 for i in range(10000)]', number=1000), "seconds")

In this case, the timeit.timeit() function is used to measure the execution time of a single line of code. The number parameter is used to specify how many times the code should be run, and the output will be the average time taken to execute the code.

cProfile module: This is a built-in Python module that provides detailed profiling information about your code, including the time spent in each function and how many times each function was called. You can run this module from the command line to profile your code, or you can use it as a library in your code.

2. cprofile module

This is another built-in Python module that provides detailed profiling information about your code, including the time spent in each function and how many times each function was called. You can run this module from the command line to profile your code, or you can use it as a library in your code.

For example;

import cProfile

def some_function():
    # code to be profiled
    x = [i**2 for i in range(10000)]"some_function()")

In this example, the function is used to profile the some_function function. The output of the code will look something like this:

         4 function calls in 0.000 seconds

   Ordered by: standard name

   ncalls  tottime  percall  cumtime  percall filename:lineno(function)
        1    0.000    0.000    0.000    0.000 <string>:1(<module>)
        1    0.000    0.000    0.000    0.000
        1    0.000    0.000    0.000    0.000<listcomp>)
        1    0.000    0.000    0.000    0.000 {built-in method builtins.exec}

The output shows the number of calls to each function, the total time spent in each function, and the cumulative time spent in each function and its subfunctions. This information can be used to identify performance bottlenecks and optimize your code.

Note that cProfile generates a lot of output, so it’s best to run it on a small piece of code first, and then scale up as needed.

3. line_profiler

This is a third-party package that provides line-by-line profiling information for your code. It can be used to find which lines of your code are taking the most time, and to optimize your code accordingly.

First, you need to install line_profiler using pip (pip install line_profiler) and then, you can use the line_profiler decorator to profile a function. For example:

from line_profiler import LineProfiler

def some_function():
    # code to be profiled
    x = [i**2 for i in range(10000)]

lp = LineProfiler()
lp_wrapper = lp(some_function)

In this example, the LineProfiler class is used to profile the some_function function. The lp_wrapper function is created by passing some_function to the lp instance, and the lp_wrapper function is then executed. Finally, the lp.print_stats() function is used to print the results of the profiling. The output will look something like this:

Timer unit: 1e-06 s

File: <ipython-input-7-1a39a0d7dc68>
Function: some_function at line 5

Line #      Hits         Time  Per Hit   % Time  Line Contents
     5                                           def some_function():
     6                                               # code to be profiled
     7       1000      278032     278.0     97.3      x = [i**2 for i in range(10000)]

The output shows the number of hits (executions) for each line of code, the total time spent on each line, and the percentage of time spent on each line. This information can be used to identify performance bottlenecks and optimize your code.

4. perf

This is a Linux tool. With perf, you can profile the entire code execution, measure the time taken by individual functions, and determine which functions are taking the most time.

An example:

First, you need to install the Linux perf tool. On Ubuntu, you can do this with:
> sudo apt-get install linux-tools-common

Next, you need to run your Python script with the perf tool, for example:
> perf record -g -F 99 python

Finally, you can generate a report of the profile results:
> perf report

In this example, the perf tool is used to profile the script. The perf record command is used to start profiling, and the -g option is used to generate call graph information. The -F 99 option is used to specify the sampling frequency (99 Hertz). The perf report command is then used to generate a report of the profile results. The report will show you information such as the function call tree, the number of samples, and the total time spent in each function.

Note that the perf tool is a Linux-specific tool, and is not available on other operating systems. Also, it requires administrative privileges to run.

5. memory_profiler

This is another third-party package that provides detailed information about the memory usage of your code. It can be used to identify memory leaks, monitor memory usage over time, and optimize memory usage in your code.

First, you need to install memory_profiler using “pip install memory_profiler”. Then, you can use the @profile decorator to profile a function. For example:

from memory_profiler import profile

def some_function():
    # code to be profiled
    x = [i**2 for i in range(10000)]


In this example, the @profile decorator is used to profile the some_function function. The some_function function is then executed, and the memory usage of the function is recorded. Finally, the results of the profiling are printed to the console. The output will look something like this:

Line #    Mem usage    Increment   Line Contents
     4   18.967 MB    0.000 MB   @profile
     5                             def some_function():
     6   18.967 MB    0.000 MB       x = [i**2 for i in range(10000)]

The output shows the memory usage of each line of code, and the incremental change in memory usage between lines. This information can be used to identify memory leaks and optimize your code.

That’s it we hope that this article was helpful. Let us know if you know any other method to benchmark Python code!


Three tools to detect if your Python 3 project has vulnerabilities

1. PyUp Safety

PyUp Safety is a tool that helps you identify and fix security vulnerabilities in your Python dependencies. It integrates with your development process, and runs continuously in the background to notify you of new vulnerabilities in your dependencies. You can also run manual scans of your code and dependencies to get a comprehensive report of all known vulnerabilities.

Here’s how PyUp Safety works:

  1. Scanning: PyUp Safety scans your dependencies and compares them against a database of known vulnerabilities. This database is constantly updated, so you always have the latest information about vulnerabilities in your dependencies.
  2. Notifications: Whenever PyUp Safety finds a vulnerability in one of your dependencies, it sends you a notification with information about the vulnerability and how to fix it.
  3. Remediation: PyUp Safety provides detailed information and guidance on how to fix each vulnerability, including recommended upgrades and patches. You can also use PyUp Safety to automate the process of upgrading your dependencies to the latest secure version.

PyUp Safety also offers additional features such as a dashboard that provides an overview of your project’s security status, and the ability to customize your notifications and remediation process to fit your specific needs.

Overall, PyUp Safety is a useful tool for anyone who is concerned about the security of their Python dependencies and wants to stay on top of any vulnerabilities.

2. Bandit

Bandit is a security-focused source code analysis tool for Python. It performs a variety of tests on your code to identify potential security vulnerabilities, including checks for issues like cross-site scripting, SQL injection, and other types of security flaws.

Bandit does the following.

  1. Analysis: Bandit analyzes your Python code and performs a series of tests to identify potential security vulnerabilities. It can be run as part of your development process or as a standalone tool.
  2. Reporting: Bandit provides detailed information about any vulnerabilities it finds in your code, including a description of the vulnerability, the severity of the issue, and the line of code where the vulnerability was detected. This information can be used to prioritize remediation efforts and track progress.
  3. Customization: Bandit provides a flexible and customizable architecture, allowing you to define your own security tests and customize the reporting format to suit your needs.

Bandit is a great tool for developers and security professionals who want to ensure the security of their Python code. It is open source, easy to use, and can be integrated into your existing development processes. By using Bandit to identify and remediate security vulnerabilities, you can help protect your applications and data from potential security threats.

3. Snyk

Note: this one has limited number of tests that you can run per month.

Snyk is a security tool that helps you find and fix vulnerabilities in your dependencies, including those written in Python. Snyk integrates with your development workflows and provides notifications when new vulnerabilities are discovered in your dependencies, so you can take action to remediate them quickly.

Here’s how Snyk works:

  1. Scanning: Snyk scans your code and dependencies and identifies known vulnerabilities. It also provides recommendations for how to fix each vulnerability, including suggested upgrades and patches.
  2. Notifications: Snyk sends notifications to keep you informed of new vulnerabilities as they are discovered, so you can take action to remediate them quickly.
  3. Remediation: Snyk provides detailed guidance on how to remediate vulnerabilities, including step-by-step instructions for upgrading dependencies to the latest secure versions. Snyk also provides the ability to automate the remediation process, so you can resolve vulnerabilities quickly and efficiently.
  4. Dashboard: Snyk provides a centralized dashboard that gives you an overview of your project’s security status, including information about the number and severity of vulnerabilities in your dependencies, and a timeline of when they were discovered.

Overall, Snyk is a powerful tool for anyone who wants to ensure the security of their dependencies. With Snyk, you can stay informed of new vulnerabilities, take action to remediate them quickly, and keep your applications and data secure.

Let me know if you know any other good ones in the comments!

Administration Development

How can I prevent SQL injection in PHP?

Disclaimer that this article talks about the best practices that you can use to decrease the likelihood of preventing SQL/MySQL injection when writing code in PHP. This, however, does not guarantee that you will never be victim to MySQL injection. You will always need to be cautious when coding and test appropriately.

1. Us PHP Data Objects (PDO Extension)

PDO is an extension for PHP that provides a common interface for accessing databases. It was introduced in PHP 5.1 and is now the recommended way to interact with databases in PHP. PDO provides a consistent, object-oriented interface for working with databases, regardless of the underlying database system (e.g., MySQL, PostgreSQL, SQLite, etc.).

In summary it can:

  1. Support for multiple database systems: PDO supports a wide range of databases, including MySQL, PostgreSQL, SQLite, MS SQL Server, Oracle, and others.
  2. Consistent interface: PDO provides a consistent interface for performing common database operations, such as executing queries, fetching data, and managing transactions.
  3. Prepared statements: PDO supports prepared statements, which allow you to execute the same statement multiple times with different parameters. Prepared statements can help prevent SQL injection attacks.
  4. Error handling: PDO provides an exception-based error handling mechanism that makes it easier to handle and debug errors in your database code.
  5. Transactions: PDO supports transactions, allowing you to execute a series of database operations as a single, atomic transaction.
  6. Easy data binding: PDO supports data binding, which allows you to bind values to placeholders in your SQL statements. This makes it easy to write secure and efficient database code.

By using PDO, you can write database-agnostic code that works with multiple database systems, and you can take advantage of its advanced features, such as prepared statements and transactions, to write secure and efficient database code. If you are developing a new PHP application, you should consider using PDO to interact with your database. If you are upgrading an existing application, you may want to consider migrating your database code to PDO to take advantage of its improved features and security.

2. Mysqli extension

Mysqli is an improved version of the MySQL extension for PHP. It provides an improved, object-oriented interface for accessing and manipulating databases in PHP. Mysqli stands for MySQL Improved.

In short it can provide you with the following.

  1. Support for both procedural and object-oriented programming styles.
  2. Support for prepared statements, which allow you to execute the same statement multiple times with different parameters. Prepared statements can help prevent SQL injection attacks.
  3. Improved security features, including support for SSL-encrypted connections and improved error handling.
  4. Improved performance, as mysqli is optimized for modern hardware and software environments.
  5. Support for transactions, allowing you to execute a series of database operations as a single, atomic transaction.
  6. Support for multiple statements, allowing you to execute multiple SQL statements with a single call to mysqli.

Mysqli is the recommended database extension for PHP, as it provides a number of improvements over the older MySQL extension. If you are developing a new PHP application, you should use Mysqli instead of the older MySQL extension. If you are upgrading an existing application, you should consider migrating from MySQL to Mysqli to take advantage of its improved features and security.

3. Limit Privileges on the database side

Limit the privileges of the database user to only the minimum required to perform its intended tasks. This way, even if an attacker is able to inject malicious code into an SQL statement, they will be limited in the actions they can take on the database.

4. Always update

Keep your PHP and database software up-to-date with the latest security patches. New vulnerabilities are often discovered and fixed in software updates, so keeping your software up-to-date is an important part of securing your application.

You should also keep the habit of subscribing to new changelogs and security newsletters. They will usually announce when there is a new vulnerability.

5. Enable error logs

If you have not done that yet you should make sure that you have error logs available. Logs take a significant space but you might think about enabling them one in a while to do an audit and check if everything is running as expected.

6. Use a web application firewall

A WAF can be used to monitor and block malicious requests, including those that attempt to exploit SQL injection vulnerabilities. You could take a popular one from Cloudflare for example. Or if cost is too high then you can also go with an open source WAF like ModSecurity.

There are other obvious ways like validating user input but this should be common sense by now. Let me know if you know any other means to secure against SQL Injection or actually any other database vulnerability in the comments!


Which management course should a software engineer do?

There are many management courses available. This article will focus on three most popular ones. Six Sigma, PMP and MBA.

Six Sigma

Six Sigma is a data-driven, continuous improvement methodology designed to eliminate defects and improve processes in an organization. It focuses on reducing variability in processes and improving efficiency and customer satisfaction. Six Sigma professionals are trained to use statistical analysis and problem-solving techniques to identify and eliminate the root causes of defects and inefficiencies.

Project Management Professional

PMP is a project management certification offered by the Project Management Institute (PMI). It is aimed at project managers who are responsible for leading and managing projects from start to finish. PMP certification requires passing an exam and demonstrating experience in leading and directing projects. PMP certified professionals have the knowledge and skills to effectively manage scope, schedule, budget, and resources, and to ensure the successful delivery of projects.

Master of Business Administration

An MBA is a graduate-level degree program in business administration that provides students with a comprehensive education in business and management. The program covers topics such as finance, marketing, operations, and strategy, and is designed to provide students with a broad understanding of business and the skills needed to lead and manage organizations. An MBA program typically involves coursework and may also include hands-on experience such as internships, case studies, and group projects.

Which one is best for software engineering?

It depends on the specific goals and career aspirations of the software engineer. Here’s a brief overview of how each of the certifications may be relevant to a software engineer:

For Six Sigma, while it may not be directly relevant to software engineering, it could be useful for software engineers who are interested in process improvement and quality control, especially if they are working in a software development organization that has adopted Six Sigma as its standard for continuous improvement.

PMP certification can be beneficial for software engineers who are interested in transitioning into project management roles, or for those who are already managing software development projects. The PMP certification provides a comprehensive understanding of project management principles, including how to manage scope, schedule, budget, and resources, and how to ensure project success.

An MBA can be valuable for software engineers who are interested in advancing their careers into management and leadership roles, especially in technology-focused organizations. An MBA program provides a broad education in business and management, including courses in finance, marketing, and strategy, which can be useful for software engineers who want to understand the business side of software development.

Ultimately, the best certification for a software engineer will depend on their individual career goals and aspirations. A software engineer may find that obtaining multiple certifications, such as PMP and Six Sigma, can be beneficial for broadening their skills and knowledge, and increasing their marketability in the job market.

Our recommendation is to start with a projection management certificate.


How to wait in Python?

In Python, you can wait or pause the execution of your code by using the time module. The time module provides several functions to handle time-related operations, including the ability to pause execution. Here’s how you can use the time.sleep() function to wait in Python:

import time


# Wait for 5 seconds


The time.sleep() function takes one argument, which is the number of seconds to wait. In the example above, the code will wait for 5 seconds before printing “End”.

It’s important to note that the time.sleep() function will pause the entire process, so it’s not suitable for applications where you need to respond to events in real-time.