Ne vous inquiétez pas, vous allez voir d'autres langages & framework

Qui je suis ?

Jonathan Boyer

  • Développeur fullstack
  • Principalement autodidacte
  • Freelance depuis 12 ans
  • Formateur /  Tutoriels vidéos sur grafikart.fr

C'est quoi le meilleur langage ?

Mon premier langage

package{
	
	import flash.display.MovieClip;
	import flash.display.Loader; 
	import flash.net.URLRequest;
    import flash.utils.Timer;
	import flash.events.Event;
    import flash.events.TimerEvent;
	import caurina.transitions.*;

	public class Diaporama extends MovieClip{
		
		var images;
		var compt:uint=0;
		var delai:Timer = new Timer(3000);
		
		public function Diaporama(list:Array):void{
			images=list;
			this.addChild(new MovieClip()); this.addChild(new MovieClip());
			delai.addEventListener(TimerEvent.TIMER,charger);
			charger();
		}
		
		private function charger(e=0){
			delai.stop();
			this.swapChildrenAt(0,1);
			this.removeChildAt(1);
			var l:Loader=new Loader();
			l.contentLoaderInfo.addEventListener(Event.COMPLETE,appar);
			l.load(new URLRequest(images[compt]));
			this.addChildAt(l,1);
			compt++;
			if(compt>=images.length){
				compt=0;
			}
		}
		private function appar(e:Event){
			this.getChildAt(1).alpha=0;
			this.getChildAt(1).x=this.getChildAt(1).y=-200;
			Tweener.addTween(this.getChildAt(1),{x:-200+(Math.round(Math.random()*2)-1)*100,y:-200+(Math.round(Math.random()*2)-1)*100, time:4, transition:"linear"});
			Tweener.addTween(this.getChildAt(1),{alpha:1, time:1, transition:"linear"});
			delai.start();
		}
	}
}

Un langage est un outil

et répond à un problème précis

« Si le seul outil que vous avez est un marteau, vous tendez à voir tout problème comme un clou »

Abraham Maslow (The Psychology of Science, 1966).

PHP

mais pour du temps réel :(

générer des pages HTML

Être développeur

= résoudre des problèmes

Apprendre un nouveau langage

oublier le langage précédent

Améliore ses compétences globales

Pourquoi apprendre un nouveau langage ?

Elixir

defmodule Discordbot.Commands.SMS do
  @moduledoc """
  Permet aux utilisateur d'alerter l'administrateur par SMS en cas de problème
  Utilise l'API de Free
  """

  alias DiscordEx.RestClient.Resources.Channel
  alias DiscordEx.RestClient.Resources.Guild

  @doc """
  Send a message on general channel
  """
  def handle(:message_create, payload = %{"content" => "!sms " <> _message}, state = %{rest_client: conn}) do
    Channel.delete_message(conn, payload["channel_id"], payload["id"])
    handle_sms(payload, state, __MODULE__)
  end

  def handle(_type, _data, state) do
    {:no, state}
  end

  def handle_sms(payload = %{"content" => "!sms " <> message}, state = %{rest_client: conn}, module) do
    if module.is_allowed(conn, payload) && !is_within_hour?(Map.get(state, :last_sms)) do
      module.send(message)
      {:ok, Map.put(state, :last_sms, :os.system_time(:seconds))}
    else
      {:no, state}
    end
  end

  defp is_within_hour?(nil) do false end
  defp is_within_hour?(time) do
    :os.system_time(:seconds) - time <= 3600
  end

  @doc """
  Send an SMS using mobile.free.fr
  """
  def send(message) do
    credentials = :discordbot |> Application.get_env(:sms) |> Keyword.get(:credentials)
    HTTPoison.get("https://smsapi.free-mobile.fr/sendmsg", [], [params: Keyword.put(credentials, :msg, message)])
  end

  @doc """
  Does the user belongs to a role that can send SMS alerts ?
  """
  def is_allowed(conn, payload) do
    expected_role = :discordbot
      |> Application.get_env(:sms)
      |> Keyword.get(:role)
    %{"guild_id" => guild_id} = Channel.get(conn, payload["channel_id"])
    %{"roles" => roles} = Guild.member(conn, guild_id, payload["author"]["id"])
    Enum.member?(roles, expected_role)
  end

end
  • La programmation fonctionnelle
    (map, reduce & filter)

  • Fonction pure

  • Immutabilité

Ce que j'ai appris

Affine ses préférences

Pourquoi apprendre un nouveau langage ?

Ruby & Ruby on Rails

class PetsController < ApplicationController

  before_action :set_pet, only: [:edit, :update, :destroy]
  skip_before_action :only_signed_in, only: [:show]

  def show
    @pet = Pet.find(params[:id])
  end

  def index
    @pets = current_user.pets
  end

  def new
    @pet = current_user.pets.new
  end

  def create
    @pet = current_user.pets.new(pet_params)
    if @pet.save
      redirect_to pets_path, success: 'Votre animal a bien été créé'
    else
      render :new
    end
  end

  def edit
  end

  def update
    if @pet.update(pet_params)
      redirect_to pets_path, success: 'Votre animal a bien été modifié'
    else
      render :edit
    end
  end

  def destroy
    @pet.destroy
    redirect_to pets_path, success: 'Votre animal a bien été supprimé'
  end

  private

  def pet_params
    params.require(:pet).permit(:name, :gender, :birthday, :species_id, :avatar_file)
  end

  def set_pet
    @pet = current_user.pets.find(params[:id])
  end

end
tomorrow = 1.days.from_now
class Integer
  
  def days
    # ....
  end
  
end

Je n'aime pas la magie :(

Ce que j'ai appris

module ImageConcern

  extend ActiveSupport::Concern

  module ClassMethods

    def has_image(field, options = {})
      options[:resize] = '150x150!' if options[:resize].nil?

      attr_accessor "#{field}_file".to_sym
      validates "#{field}_file".to_sym, file: {ext: [:jpg, :png]}
      after_save "#{field}_after_upload".to_sym
      before_save "#{field}_before_upload".to_sym
      after_destroy_commit "#{field}_destroy".to_sym

      class_eval <<-METHODS, __FILE__, __LINE__ + 1
        def #{field}_url(format = nil)
          format = "_\#{format}" unless format.nil?
          '/uploads/' + [
            self.class.name.downcase.pluralize,
            id.to_s,
            "#{field}\#{format}.jpg"
          ].join('/')
        end

        def #{field}_path
          File.join(
            Rails.public_path,
            'uploads',
            self.class.name.downcase.pluralize,
            id.to_s,
            '#{field}.jpg'
          )
        end

        private
      
        def #{field}_before_upload
          if #{field}_file.respond_to?(:path) and self.respond_to?(:#{field})
            self.#{field} = true
          end
        end
      
        def #{field}_after_upload
          path = #{field}_path
          options = #{options}
          if #{field}_file.respond_to? :path
            dir = File.dirname(path)
            FileUtils.mkdir_p(dir) unless Dir.exist?(dir)
            image = MiniMagick::Image.new(#{field}_file.path) do |b|
              if options[:resize].ends_with?('!') 
                b.resize '#{options[:resize].delete('!')}^'
                b.gravity 'Center'
                b.crop '#{options[:resize].delete('!')}+0+0'
              else
                b.resize '#{options[:resize].delete('!')}\>'
              end
            end
            image.format 'jpg'
            image.write path
            if options[:formats]
              options[:formats].each do |k, v|
                image = MiniMagick::Image.new(#{field}_file.path) do |b|
                  b.resize "\#{v}^"
                  b.gravity 'Center'
                  b.crop "\#{v}+0+0"
                end
                image.format 'jpg'
                image.write path.gsub('.jpg', "_\#{k}.jpg")
              end
            end
          end
        end
      
        def #{field}_destroy
          dir = File.dirname(#{field}_path)
          FileUtils.rm_r(dir) if Dir.exist?(dir)
        end
      METHODS
    end

  end

end
class Post
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue(strategy="IDENTITY")
     * @ORM\Column(type="integer")
     */
    private ?int $id = null;

    private string $type = '';

    /**
     * @ORM\Column(type="string", length=255)
     */
    private ?string $title = null;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private ?string $slug = null;

    /**
     * @ORM\Column(type="text")
     */
    private ?string $content = null;

    /**
     * @ORM\Column(type="datetime")
     */
    private ?\DateTimeInterface $createdAt = null;

    /**
     * @ORM\Column(type="datetime")
     */
    private ?\DateTimeInterface $updated_at = null;

    /**
     * @ORM\Column(type="boolean", options={"default": 0})
     */
    private bool $online = false;

    /**
     * @ORM\ManyToOne(targetEntity="App\Domain\Attachment\Attachment", cascade={"persist"})
     * @ORM\JoinColumn(name="attachment_id", referencedColumnName="id")
     */
    private ?Attachment $image = null;

    /**
     * @ORM\ManyToOne(targetEntity="App\Domain\Auth\User")
     * @ORM\JoinColumn(name="user_id", referencedColumnName="id")
     */
    private ?User $author = null;

    /**
     * @ORM\OneToMany(targetEntity="App\Domain\Course\Entity\TechnologyUsage", mappedBy="content", cascade={"persist"})
     *
     * @var Collection<int, TechnologyUsage>
     */
    private Collection $technologyUsages;

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getTitle(): ?string
    {
        return $this->title;
    }

    /**
     * @param string $title
     *
     * @return $this
     */
    public function setTitle(?string $title): self
    {
        $this->title = $title;

        return $this;
    }

  
 }
class Post extends Eloquent
{
  
}

Laravel

Symfony

$post = Post::find(12);
$post->title // "Hello World"

Vous n'êtes pas obligé de maitriser

Connaitre les forces / faiblesses suffit

C'est quoi le meilleur langage ?

Par quel langage je devrais commencer ?

C'est quoi le meilleur langage ?

Conclusion

  • Commencez et pratiquez !
  • Focalisez vous sur vos connaissances (plus que les langages)
  • Soyez ouvert d'esprit !
  • Les langages sont un moyen, pas une fin

Questions ?

PHP, à l'ancienne

<?php

if(!empty($_FILES)){
	require("imgClass.php");
	$img = $_FILES['img'];
	$ext = strtolower(substr($img['name'],-3));
	$allow_ext = array("jpg",'png','gif');
	if(in_array($ext,$allow_ext)){
		move_uploaded_file($img['tmp_name'],"images/".$img['name']);
		Img::creerMin("images/".$img['name'],"images/min",$img['name'],215,112);
		Img::convertirJPG("images/".$img['name']);
	}
	else{
		$erreur = "Votre fichier n'est pas une image";
	}

}

?><!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN"
"http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="fr" lang="fr">
<head>
<script type="text/javascript" src="zoombox/jquery.js"></script>
<script type="text/javascript" src="zoombox/zoombox.js"></script> 
<link rel="stylesheet" type="text/css" href="theme/style.css" /> 
<link href="zoombox/zoombox.css" rel="stylesheet" type="text/css" media="screen" />
</head>

<body>
<?php
if(isset($erreur)){
	echo $erreur;
}

?>
<form method="post" action="index.php" enctype="multipart/form-data">
<input type="file" name="img"/>
<input type="submit" name="Envoyer"/>
</form>

<?php
$dos = "images/min";
$dir = opendir($dos);
while($file = readdir($dir)){
	$allow_ext = array("jpg",'png','gif');
	$ext = strtolower(substr($file,-3));
	if(in_array($ext,$allow_ext)){
		?>
		<div class="min">
		<a href="images/<?php echo $file; ?>" rel="zoombox[galerie]">
		<img src="images/min/<?php echo $file; ?>"/>
		<h3><?php echo $file; ?></h3>
		</a>
		</div>
		<?php
	}
}
?>
</body>

</html>

CakePHP

Merci @_jails_

  • La programmation orientée objet

  • Model View Controller

  • L'utilisation de librairies tiers

Ce que j'ai appris

Laravel

<?php namespace App\Http\Controllers;


class PetsController extends Controller {

	public function getResource($id){
		return Pet::findOrFail($id);
	}

	public function index(Guard $auth)
	{
		$pets = $auth->user()->pets;
		$pets->load('species');
		return view('pets.index', compact('pets'));
	}

	public function edit($pet)
	{
		return view('pets.edit', compact('pet'));
	}

	public function update($pet, PetsRequest $request, Guard $auth)
	{
		$data = $request->all();
		$data['user_id'] = $auth->user()->id;
		$pet->update($data);
		return redirect(action('PetsController@index'))->with('success', 'L\'espèce a bien été modifiée');
	}


}
  • L'injection de dépendance

  • Le container

  • La magie 

Ce que j'ai appris

La magie ?

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Model;

class Post extends Model
{

}


$post = Post::find(1);

$post->title; // 'Mon titre'
  • La magie c'est dangereux

Symfony

class Post
{
    /**
     * @ORM\Id()
     * @ORM\GeneratedValue(strategy="IDENTITY")
     * @ORM\Column(type="integer")
     */
    private ?int $id = null;

    private string $type = '';

    /**
     * @ORM\Column(type="string", length=255)
     */
    private ?string $title = null;

    /**
     * @ORM\Column(type="string", length=255)
     */
    private ?string $slug = null;

    /**
     * @ORM\Column(type="text")
     */
    private ?string $content = null;

    /**
     * @ORM\Column(type="datetime")
     */
    private ?\DateTimeInterface $createdAt = null;

    /**
     * @ORM\Column(type="datetime")
     */
    private ?\DateTimeInterface $updated_at = null;

    /**
     * @ORM\Column(type="boolean", options={"default": 0})
     */
    private bool $online = false;

    /**
     * @ORM\ManyToOne(targetEntity="App\Domain\Attachment\Attachment", cascade={"persist"})
     * @ORM\JoinColumn(name="attachment_id", referencedColumnName="id")
     */
    private ?Attachment $image = null;

    /**
     * @ORM\ManyToOne(targetEntity="App\Domain\Auth\User")
     * @ORM\JoinColumn(name="user_id", referencedColumnName="id")
     */
    private ?User $author = null;

    /**
     * @ORM\OneToMany(targetEntity="App\Domain\Course\Entity\TechnologyUsage", mappedBy="content", cascade={"persist"})
     *
     * @var Collection<int, TechnologyUsage>
     */
    private Collection $technologyUsages;

    public function getId(): ?int
    {
        return $this->id;
    }

    public function getTitle(): ?string
    {
        return $this->title;
    }

    /**
     * @param string $title
     *
     * @return $this
     */
    public function setTitle(?string $title): self
    {
        $this->title = $title;

        return $this;
    }

  
 }

L'apprentissage est cumulatif

 

 

Plus on apprend, plus on comprend vite

Soyez patient

et curieux !

mais pas trop :)

Made with Slides.com