Mise en place d'un serveur LAMP (Linux,Apache,MariaDb,Php)

Informations pour bien débuter en PureBasic
Avatar de l’utilisateur
microdevweb
Messages : 1798
Inscription : mer. 29/juin/2011 14:11
Localisation : Belgique

Mise en place d'un serveur LAMP (Linux,Apache,MariaDb,Php)

Message par microdevweb »

Bonjour à tous,

Voici une vidéo tutoriel sur la mise en place d'un serveur LAMP (Linux,Apache,Mysql (MariaDb),Php) ainsi que phpMyAdmin dans une machine virtuel.

Je détaille également les différents réglages pour pouvoir être utilisé avec PureBasic. Juste une connexion à une base de données.

Par la suite je réaliserais une deuxième partie, avec une gestion élémentaire en Pb.

https://youtu.be/MCfvlt1GxnU

Petit exemple d'application, j'ai séparé mon code en deux partie dont un module qui ne s'occupe que des transaction mySql. Pour que cela fonctionne chez vous vous devez remplacer l'adresse ip, le nom de la base l'utilisateur et le mot de passe en fonction de votre serveur.

Remarque : une application de ce type aurais besoins d'un threath de rafraîchissement et comme je n'ai pas trouvé également de méthodes pour savoir quel record est locked, je ferais perso un table pour gérer cela. Il est évident que la gestion d'un db réseau demande de la rigueur et plus de travail.

ATTENTION : L'exécutable autonome à besoin de la dll mariaDb pour fonctionner.
Image

module DB

Code : Tout sélectionner

DeclareModule DB
  Global ipAddress.s = "192.168.1.12"
  Global user.s = "post_2"
  Global psw.s = "1234"
  Global dbName.s = "test"
  
  Declare new()
  
  Interface db
    setFloat(value.f,column)
    setLong(value.l,column)
    setString(value.s,column)
    setQuad(value.q,column)
    getFloat.f(column)
    getString.s(column)
    getLong.l(column)
    getQuad.q(column)
    query(request.s)
    update(request.s)
    nextRecord()
    close()
  EndInterface
EndDeclareModule

Module DB
  EnableExplicit
  UseMySQLDatabase()
  
  Structure _struct
    *methods
    conectionId.l
  EndStructure
  
  Procedure new()
    Protected *this._struct = AllocateStructure(_struct)
    With *this
      ; try to connect
      \conectionId = OpenDatabase(#PB_Any,"host="+ipAddress+" port=3306 dbname="+dbName,user, psw)
      ; if connection failed
      If Not \conectionId
        MessageRequester("DATABASE ERROR","Cannot connect to database "+DatabaseError(),#PB_MessageRequester_Error)
        ProcedureReturn #False
      EndIf
      \methods = ?S_MTH
      ; return object instance
      ProcedureReturn *this
    EndWith
  EndProcedure
  
  Procedure close(*this._struct)
    With *this
      If IsDatabase(\conectionId)
        CloseDatabase(\conectionId)
      EndIf
      FreeStructure(*this) ; free object instance
    EndWith
  EndProcedure
  
  Procedure setFloat(*this._struct,value.f,column)
    With *this
      If \conectionId
        SetDatabaseFloat(\conectionId,column,value)
      EndIf
    EndWith
  EndProcedure
  
  Procedure setLong(*this._struct,value.l,column)
    With *this
      If \conectionId
        SetDatabaseLong(\conectionId,column,value)
      EndIf
    EndWith
  EndProcedure
  
  Procedure setString(*this._struct,value.s,column)
    With *this
      If \conectionId
        SetDatabaseString(\conectionId,column,value)
      EndIf
    EndWith
  EndProcedure
  
  Procedure setQuad(*this._struct,value.q,column)
    With *this
      If \conectionId
        SetDatabaseQuad(\conectionId,column,value)
      EndIf
    EndWith
  EndProcedure
  
  Procedure.f getFloat(*this._struct,column)
    With *this
      If \conectionId
       ProcedureReturn GetDatabaseFloat(\conectionId,column)
     EndIf
     ProcedureReturn 0
    EndWith
  EndProcedure
  
  Procedure.l getLong(*this._struct,column)
    With *this
      If \conectionId
        ProcedureReturn GetDatabaseLong(\conectionId,column)
      EndIf
      ProcedureReturn 0
    EndWith
  EndProcedure
  
  Procedure.s getString(*this._struct,column)
    With *this
      If \conectionId
        ProcedureReturn GetDatabaseString(\conectionId,column)
      EndIf
      ProcedureReturn ""
    EndWith
  EndProcedure
  
  Procedure getQuad(*this._struct,column)
    With *this
      If \conectionId
        ProcedureReturn GetDatabaseQuad(\conectionId,column)
      EndIf
      ProcedureReturn 0
    EndWith
  EndProcedure
  
  Procedure query(*this._struct,request.s)
    With *this
      Protected returnedValue.b =#False
      If \conectionId
        If Not DatabaseQuery(\conectionId,request)
          MessageRequester("QUERY REQUEST ERROR",request+Chr(10)+DatabaseError(),#PB_MessageRequester_Error)
        Else
          returnedValue = #True
        EndIf
      EndIf
      ProcedureReturn returnedValue
    EndWith
  EndProcedure
  
  Procedure update(*this._struct,request.s)
    Protected returnedValue.b = #False
    With *this
      If \conectionId
        If Not DatabaseUpdate(\conectionId,request)
          MessageRequester("UPDATE REQUEST ERROR",request+Chr(10)+DatabaseError(),#PB_MessageRequester_Error)
        Else
          returnedValue = #True
        EndIf
        close(*this)
      EndIf
      ProcedureReturn returnedValue
    EndWith
  EndProcedure
  
  Procedure nextRecord(*this._struct)
    With *this
      ProcedureReturn NextDatabaseRow(\conectionId)
    EndWith
  EndProcedure
  
  
  
  DataSection
    S_MTH:
    Data.i @setFloat()
    Data.i @setLong()
    Data.i @setString()
    Data.i @setQuad()
    Data.i @getFloat()
    Data.i @getString()
    Data.i @getLong()
    Data.i @getQuad()
    Data.i @query()
    Data.i @update()
    Data.i @nextRecord()
    Data.i @close()
    E_MTH:
  EndDataSection
EndModule
main code

Code : Tout sélectionner

XIncludeFile "db.pbi"
Enumeration 
  #MAIN_FORM
  #CUST_FORM
EndEnumeration
Enumeration 
  #LST
  #BT_ADD
  #BT_DELETE
  #BT_EDIT
  #FNAME
  #LNAME
  #BT_VALIDATE
  #BT_CANCEL
EndEnumeration

Declare fillCustomers()

Procedure createClientTable()
  Protected myDb.DB::db = DB::new()
  Protected req.s
  If myDb
    req = "CREATE TABLE IF NOT EXISTS customers ("+
          "id int AUTO_INCREMENT,"+
          "firstname VARCHAR(60),"+
          "lastname VARCHAR(60),"+
          "PRIMARY KEY (id))"
    myDb\update(req)
  EndIf
EndProcedure

Procedure exit()
  CloseWindow(#MAIN_FORM)
  End
EndProcedure

Procedure fillCustomers()
  Protected myDb.DB::db = DB::new()
  Protected req.s = "SELECT id,lastname,firstname FROM customers ORDER BY lastname,firstname"
  ; send query request
  If myDb\query(req)
    ; erase customers list
    ClearGadgetItems(#LST) 
    ; look for all list
    Protected index = 0 ; current list index
    While myDb\nextRecord()
      Protected line.s = myDb\getString(1)+Chr(10)+myDb\getString(2)
      AddGadgetItem(#LST,-1,line)
      ; we put record id at current index
      SetGadgetItemData(#LST,index,myDb\getLong(0))
      index + 1
    Wend
    ; don't forget to close the database
    myDb\close()
  EndIf
EndProcedure

Procedure closeCustomer()
  CloseWindow(#CUST_FORM)
EndProcedure

Procedure fillDetail(id)
  Protected myDb.DB::db = DB::new()
  Protected req.s = "SELECT firstname,lastname FROM customers WHERE id = ? FOR UPDATE"
  myDb\setLong(id,0)
  ; we use FOR UPDATE for looked the record
  If myDb\query(req)
    If myDb\nextRecord()
      SetGadgetText(#LNAME,myDb\getString(1))
      SetGadgetText(#FNAME,myDb\getString(0))
    EndIf
  EndIf
  myDb\close() ; close db and free object instance
EndProcedure

Procedure evAdd()
  If Not Len(GetGadgetText(#LNAME))
    MessageRequester("Field empty","you must fill the Last name",#PB_MessageRequester_Warning)
    ProcedureReturn 
  EndIf
  Protected myDb.DB::db = DB::new()
  Protected req.s = "INSERT INTO customers (firstname,lastname) VALUES (?,?)"
  If myDb
    myDb\setString(GetGadgetText(#LNAME),0)
    myDb\setString(GetGadgetText(#FNAME),1)
    myDb\update(req)
    fillCustomers()
    closeCustomer()
  EndIf
EndProcedure

Procedure evUpdate()
  Protected index = GetGadgetState(#LST)
  If Not Len(GetGadgetText(#LNAME))
    MessageRequester("Field empty","you must fill the Last name",#PB_MessageRequester_Warning)
    ProcedureReturn 
  EndIf
  ; a record is selected
  If index
    Protected id = GetGadgetItemData(#LST,index)
    Protected myDb.DB::db = DB::new()
    Protected req.s = "UPDATE customers SET firstname=?,lastname=? WHERE id = ?"
    If myDb
      myDb\setString(GetGadgetText(#FNAME),0)
      myDb\setString(GetGadgetText(#LNAME),1)
      myDb\setLong(id,2)
      If myDb\update(req)
        fillCustomers()
        closeCustomer()
      EndIf
    EndIf
  EndIf
EndProcedure


Procedure openCustomerDetails(id = 0)
  Protected x = 10,y = 10,h = 30,M = 10,w = 180
  OpenWindow(#CUST_FORM,0,0,200,190,"Customer details",#PB_Window_SystemMenu|#PB_Window_WindowCentered,WindowID(#MAIN_FORM))
  TextGadget(#PB_Any,x,y,w,h,"First name")
  y+h
  StringGadget(#FNAME,X,Y,w,h,"")
  y+h+m
  TextGadget(#PB_Any,x,y,w,h,"Last name")
  y+h
  StringGadget(#LNAME,X,Y,w,h,"")
  y+h+m
  ButtonGadget(#BT_VALIDATE,x,y,80,h,"Validate")
  x + 90
  ButtonGadget(#BT_CANCEL,x,y,80,h,"Chancel")
  ; if id = 0 we are in new mode edition else in editing mode
  If Not id
    BindGadgetEvent(#BT_VALIDATE,@evAdd())
  Else
    BindGadgetEvent(#BT_VALIDATE,@evUpdate())
    fillDetail(id)
  EndIf
  BindEvent(#PB_Event_CloseWindow,@closeCustomer(),#CUST_FORM)
  BindGadgetEvent(#BT_CANCEL,@closeCustomer())
EndProcedure

; main form event management
Procedure evEdit()
  Protected index = GetGadgetState(#LST)
  ; a record is selected
  If index
    Protected id = GetGadgetItemData(#LST,index)
    openCustomerDetails(id)
  EndIf
EndProcedure

Procedure evNew()
  openCustomerDetails(0)
EndProcedure

Procedure evDelete()
  
EndProcedure

Procedure openMainForm()
  OpenWindow(#MAIN_FORM,0,0,800,600,"Customers list",#PB_Window_ScreenCentered|#PB_Window_SystemMenu)
  ListIconGadget(#LST,10,10,680,580,"first name",340)
  AddGadgetColumn(#LST,1,"last name",330)
  ButtonGadget(#BT_ADD,700,10,90,30,"Add")
  ButtonGadget(#BT_EDIT,700,10+40,90,30,"Edit")
  ButtonGadget(#BT_DELETE,700,10+80,90,30,"Delete")
  fillCustomers()
  BindEvent(#PB_Event_CloseWindow,@exit(),#MAIN_FORM)
  BindGadgetEvent(#BT_ADD,@evNew())
  BindGadgetEvent(#BT_EDIT,@evEdit())
EndProcedure

createClientTable()
openMainForm()
Repeat:WaitWindowEvent():ForEver
Dernière modification par microdevweb le sam. 15/juin/2019 9:28, modifié 1 fois.
Windows 10 64 bits PB: 5.70 ; 5.72 LST
Work at Centre Spatial de Liège
Ollivier
Messages : 4190
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: Mise en place d'un serveur LAMP (Linux,Apache,MariaDb,Ph

Message par Ollivier »

Salut,

au niveau de l'accès à ton film, j'ai rien compris : 5 mégaoctets par seconde sur ma daube Samsung. T'es sponsorisé ?!!

J'ai apprécié le visionnage par curiosité. Le global est très bien puisque tu indiques d'une traite de manière pragmatique comment installer un système L.A.M.P. .

Maintenant, un petit peu de critique (constructive).

- Montrer un plan simple : Informatique ( Windows ; Linux )
alors c'est bien facile si je faisais le schéma (Informatique en bas, Linux à gauche et Windows à droite, et deux flèche, une pour chacun depuis le mot << informatique >> )

- Dire d'où tu viens : ton matos de départ (x86 ou ARM, vitesse et nombre de coeurs), ton OS (Windows 10 ou Ubuntu, ce sont mes a priori d'une simple vision, j'ai pas fait attention)

- Faire un bref rappel des pratiques commerciales des uns et des autres (2/3 phrases pour chacun des OS)

- Pour chaque étape L, A, M et P, à défaut de réciter les licenses (qui sont longues, ennuyeuses et pompeuses) au moins donner les noms et adresses mail des principaux contributeurs, c'est-à-dire mettre en évidence ceux qui ont permis de réaliser cette installation, même si c'est toute une foule de personnes, au moins synthétiser ceux qui sont présentés dans chaque rubrique << À propos de... >>.

- Eventuellement, faire un tout petit exemple vraiment simplissime en PureBasic : stocker les prénoms des Daltons dans la base de données.

Voilà mon petit lot de remarques. J'insiste vraiment sur leur aspect non destructif puisque ta réalisation, c'est du travail et un esprit partageur.
Avatar de l’utilisateur
microdevweb
Messages : 1798
Inscription : mer. 29/juin/2011 14:11
Localisation : Belgique

Re: Mise en place d'un serveur LAMP (Linux,Apache,MariaDb,Ph

Message par microdevweb »

@Ollivier,

Merci pour ces remarques constructives, j'avoue que j'ai fait cette vidéo car une question à été posée sur le forum pour les bd réseaux et je n'avais jamais vraiment essayé (avant je faisais mes développements en windev). Donc pour ma propre culture j'ai testé et j'ai voulu en faire profité les autres, concernant l’exemple il en cours de réalisation. Il faudrait aussi que j'essaye après PostgreSql qui est plus adapté à une gestion desktop.
Windows 10 64 bits PB: 5.70 ; 5.72 LST
Work at Centre Spatial de Liège
Ollivier
Messages : 4190
Inscription : ven. 29/juin/2007 17:50
Localisation : Encore ?
Contact :

Re: Mise en place d'un serveur LAMP (Linux,Apache,MariaDb,Ph

Message par Ollivier »

Ben après c'est une question de temps à pouvoir consacrer. Ça doit faire 3 semaines que j'ai commencé à répondre à une question aussi. Zorro demandait à mieux voir un graphe : je fais évoluer mon code de temps à autre quand c'est possible d'allumer un ordi. Alors je ne vais pas te jeter la pierre, loin de là.

Je pense que tu réponds indirectement à une question sur le traitement des bases de données en PB. Et c'est, quelquepart la bonne réponse : mettre en place un serveur solide (ce que j' appelle l' << extra-terrestre >> ! ) avec lequel la librairie de PureBasic va pouvoir communiquer pour traiter une base de données.
Marc56
Messages : 2146
Inscription : sam. 08/févr./2014 15:19

Re: Mise en place d'un serveur LAMP (Linux,Apache,MariaDb,Ph

Message par Marc56 »

Il faudrait aussi que j'essaye après PostgreSql qui est plus adapté à une gestion desktop.
Pas plus que MySQL, mais à préférer car il respecte scrupuleusement la norme contrairement à MySQL/MariaDB et même Oracle qui font une interprétation personnelle.

Pas besoin d'installer une VM (qui consommer de la RAM et du CPU), les deux SGBDR fonctionnent en tant que service réseau. Il n'y a donc pas de différence entre l'accès local ou distant.

:idea: Bonus
Quelques outils que je recommande pour manager les bases SQL:
Pour SQLite: SQLiteStudio
Pour MySQL/MariaDB et PostgreSQL: HeidiSQL
Sont tous les deux: Windows natif (pas besoin de Java ou d'un serveur http), Freeware, légers, mieux que PHPMyAdmin.
Pour ceux qui ont un serveur http avec PHP, Adminer est pas mal aussi. (Un seul fichier PHP à copier sur le serveur)

PS. Pour ton cours, pense à préciser qu'il faut dé-valider l'AUTOCOMMIT de MySQL ou faire les SELECT ... FOR UPDATE dans une transaction. Sans cela la modification est effective dès envoi.

Bonne continuation. :wink:
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: Mise en place d'un serveur LAMP (Linux,Apache,MariaDb,Ph

Message par djes »

Merci pour les outils Marc. Au boulot on fait du SIG avec SQLite (format geopackage), PostgreSQL et QGIS et ça pourrait m'aider. D'ailleurs je cherche un bon outil pour les GeoTIF et un bon soft pour faire du relevé terrain sur Android car pour l'instant mes tests avec QField donnent des résultats assez moyens.
Avatar de l’utilisateur
microdevweb
Messages : 1798
Inscription : mer. 29/juin/2011 14:11
Localisation : Belgique

Re: Mise en place d'un serveur LAMP (Linux,Apache,MariaDb,Ph

Message par microdevweb »

@Marc56,

Merci pour tes conseils, j'avoue n'être pas un pro en réseaux (je déteste ça d’ailleurs) mais dans le cadre de mon cursus (informatique industriel et système) j'ai été obligé d'en apprendre les bases ainsi q'un cour d’architecture système ou franchement le prof conseille des VM et est plutôt linux que windows. Maintenant si je devais faire un soft avec Db réseaux pour un client je préférerais ProtgreSql car il gère les trigers etc, mais encore une fois de plus je n'ai pas testé donc la suite au prochain épisode.
Windows 10 64 bits PB: 5.70 ; 5.72 LST
Work at Centre Spatial de Liège
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: Mise en place d'un serveur LAMP (Linux,Apache,MariaDb,Ph

Message par djes »

Perso je comprends le prof, une vm ça se restaure très vite en cas de problème (mais il faut bien penser au backup des données).
Je comprends aussi Marc car en général pour ses propres travaux on préfère garder un maximum de contrôle, de vitesse etc.
Avatar de l’utilisateur
Zorro
Messages : 2185
Inscription : mar. 31/mai/2016 9:06

Re: Mise en place d'un serveur LAMP (Linux,Apache,MariaDb,Ph

Message par Zorro »

Image

hum...je pense que depuis le temps que tu fait ce geste, tu ne dois plus avoir de cheveux sous les mains ...
on dois t'appeler "chaussé au moines" non ? :lol:

Image
Image
Image
Site: http://michel.dobro.free.fr/
Devise :"dis moi ce dont tu as besoin, je t'expliquerai comment t'en passer"
Avatar de l’utilisateur
djes
Messages : 4252
Inscription : ven. 11/févr./2005 17:34
Localisation : Arras, France

Re: Mise en place d'un serveur LAMP (Linux,Apache,MariaDb,Ph

Message par djes »

Damned, c'est à cause de ça, j'aurais dû y penser ! Au moins la tonsure donne-t-elle (aux autres) l'illusion de la sagesse...
Répondre