روش استفاده از دیزاین پترن singleton در لاراول

ابتدا در serivceProvider درون متد register به صورت زیر کلاس مورد نظر را تعریف میکنیم مزیت استفاده از singleton این است که فقط برای یکبار new میشود و هر جا میتوان از آن خیلی ساده استفاده کرد. این امر موجب بهینه سازی مصرف Ram و ارتقا سرعت نیز میگردد

    $this->app->singleton(Hasher::class, function () {
        return new Hasher();
    });

و سپس بدین شکل از آن استفاده میکنم

\Hasher::generate()

به طور مثال در کلاس Hasher

<?php

namespace Gallib\ShortUrl;

class Hasher
{
    /**
     * @var int
     */
    protected $length = 6;

    public function setLength(int $length): self
    {
        $this->length = $length;

        return $this;
    }

    /**
     * Generate a random hash.
     *
     * @return string
     */
    public function generate(): string
    {
        $characters = str_repeat('abcdefghijklmnoKLMNOPQRSTUVWXYZ0123456789', $this->length);

        return substr(str_shuffle($characters), 0, $this->length);
    }
}

سرور تست ایمیل با MailHog

برنامه نویسان برای اینکه از صحت کارکرد ارسال ایمیل مطمن شوند و طراحی قالب ایمیل ها را در محیط تست چک کنند نیاز به یک سرویس ایمیل می باشد که یکی از بهترین آنها MailHog است.

در این روش با کمک داکر میتوانید به صورت نامحدود ایمیل های تستی ارسال کنید و هیچ وابستگی به سایت و سرویس دهنده ای نخواهید داشت.

در ابتدا docker را نصب کنید . و سپس یک فایل با عنوان docker-compose.yml را ایجاد نمایید و دستور زیر را در وارد میکنیم

touch docker-compose.yml
version: "3.7"
services:

  # SMTP Server
  smtp:
    platform: linux/x86_64
    image: mailhog/mailhog
    container_name: docker-workspace-smtp
    logging:
      driver: 'none'
    ports:
      - "8003:1025"
      - "8100:8025"
    networks:
      - docker_workspace_network

networks:
  docker_workspace_network:
    driver: bridge

در نهایت با وارد کردن دستور

docker compose up -d

نصب انجام میشود جهت مشاهده mailHog وارد آدرس http://IP:8100 شوید

به جای IP باید IP ماشین مجازی را وارد کنید که با دستور ip a در ابونتو قابل دریافت است

در لاراول فایل .env را به مقادیر زیر تغییر دهید و در سایر سرویس ها مقادیر را معادل نمونه زیر در نظر بگیرید

MAIL_MAILER=smtp
MAIL_HOST=IPaddress
MAIL_PORT=8003
MAIL_USERNAME=''
MAIL_PASSWORD=''
MAIL_ENCRYPTION=null

Eager Loading چطور در لاراول استفاده کنیم

به صورت معمولی اگر شما یک رابطه در مدل Flat داشته باشید که به جدول دیگر رابطه یک به یک داشته باشید hasOne به شکل زیر میتوان از ان استفاده کرد

$cars = App\Flat::all();
 
    foreach ($flats as $flat) {
      echo $flat->owner->name;
    }

در روش فوق به ازای هر لوپ یکبار به جدول owner ارجاع میکند یعنی اگر ۱۰۰ تا رکورد باشد ۱۰۰ بار لوپ اجرا میشود و ۱۰۱ بار به دیتابیس کانکت میشوید تا مقادیر رابطه hasOne در sql اجرا میشود .

روش بهتر استفاده از eager loading است

$flats = App\Flat::with('owner')->get();
 
    foreach ($flats as $flat) {
      echo $flat->owner->name;
    }

در روش فوق به نوعی به جدول owner join زده شده و در هر لوپ از مقادیری که در select اول داشته ایم استفاده میشود در واقع ۱۰۰ بار لوپ اجرا میشود و یکبار هم به دیتابیس متصل میشود.

دستورات import و export دیتابیس mysql در محیط داکر docker

برای گرفت export از دیتابیس دستور زیر را اجرا نمایید

docker exec docker-test-db-1 /usr/bin/mysqldump -u root --password=secret laravel --no-tablespaces > dump000916-3.sql

docker-test-db-1 همان container name است که با دستور docker ps بدست می آید

laravel نام دیتابیسی است که باید export گرفته شود

dump000916-3.sql نام فایلی است که export گرفته میشود

جهت ورود اطلاعات به دیتابیس import از دستور زیر

docker exec -i docker-test-db-1 /usr/bin/mysql -u root --password=secret laravel --init-command="SET SESSION FOREIGN_KEY_CHECKS=0;" < dump000916-3.sql

docker-test-db-1 همان container name است که با دستور docker ps بدست می آید

laravel نام دیتابیسی است که باید import گرفته شود

dump000916-3.sql نام فایلی است که import میشود

command=”SET SESSION FOREIGN_KEY_CHECKS=0;” کاری میکند که اگر در هنگام ورود خطای foregen key check error بود صرف نظر کند

نصب داکر در لینوکس بدون تحریم و کندی سرعت

در این آموزش شما را با یک روش بسیار ساده جهت دور زدن تحریم های داکر و نصب داکر در سرور ایران آشنا خواهم کرد. این آموزش دو روش نصب و اجرا دارد که روش اول روش پیشنهاد بوده که نیازی به تغییر DNS و اجرای تحریم شکن روی سرور ندارد بلکه با نصب داکر از طریق snap در ubuntu به خوبی میتوانید هسته داکر را روی اوبونتو نصب و بدون مشکل آپدیت کنید.

همچنین برای نصب image ها از مدخل هایی که در ایران برای دور زدن تحریم های داکر ایجاد شده اند استفاده میکنید که استفاده از این مدخل ها هم هیچ نیازی به نصب تحریم شکن و تغییر DNS و پرداخت هزینه ای نیست.

مراحل اجرا

۱- نصب داکر

۲- نصب ایمیج هایی که در پروژه خود لازم دارید

مرحله اول توصیه میکنم از دستور ساده نصب داکر در بسته snap در ubuntu استفاده کنید و صرفا با یک خط کد زیر انجام میشود. و نیازی به هیچ ابزار خاص دیگری نیست…

sudo snap install docker

سپس برای اینکه بتوانید همه image های داکر را بدون تحریم دریافت کنید دستور زیر را اضافه کنید که از مخزن آروان استفاده کنید یعنی آروان میرود image مورد نظر شما را دریافت میکند و شما از آروان تحویل میگیرد نه از سایت تحریم شده

sudo bash -c 'cat > /var/snap/docker/current/config/daemon.json <<EOF
{
  "insecure-registries" : ["https://docker.arvancloud.ir"],
  "registry-mirrors": ["https://docker.arvancloud.ir"]
}
EOF'

سپس با چند دستور داکر را ریست کنید.

sudo snap restart docker

حال برای اینکه مطمن شوید کار به درستی انجام شده دستور زیر را برای نصب container hello world اجرا کنید

sudo docker run hello-world

همچنین شما میتوانید از مخزن docker.ir هم برای دانلود image های داکر نیز استفاده کنید . کافی است به جای دستور استفاده از مخزن آروان دستور زیر را وارد کنید

sudo bash -c 'cat > /var/snap/docker/current/config/daemon.json <<EOF
{
  "registry-mirrors": ["https://registry.docker.ir"]
}
EOF'

سپس داکر را ریست کنید

sudo snap restart docker

روش دوم نصب داکر با استفاده از راهنمای سایت اصلی (نیاز به شکن و تحریم شکن صرفا در مرحله نصب خود نرم افزار داکر را دارد)

فعال سازی شکن ، در این مرحله شما وارد بخش مدیریت dns میشوید به پایین صفحه بروید و معمولا ۳ خط کد به صورت کامنت نشده است که آنها را کامنت کنید چرا که بعد از پایین مرحله دوم باید آنها را مجدد از کامنت خارج کنید که همیشه سرور شما با dns های شکن نباشد. (صرفا موقع به نصب و روزرسانی شکن فعال شود )

sudo nano /etc/resolv.conf

DNS های شکن را مطابق زیر در فایل فوق وارد کنید. و با CTRL+X و زدن Y تنظیمات را ذخیره میکنیم.

nameserver 178.22.122.100
nameserver 185.51.200.2 

خوب الان میشه دستورات نصب داکر را اجرا کرد . با دستور زیر وارد root شوید

sudo -i

و مطابق راهنمای اصلی سایت داکر اقدام کنید

https://docs.docker.com/engine/install/ubuntu/#install-using-the-repository

تا اینجا اگر خوب پیش رفته باشید با زدن دستور docker -v باید نسخه نصب شده را نمایش دهد . کار نصب انجام شد . حالا میتوانید dns های شکن را بردارید و شروع به فعال سازی docker.ir کنید که بتوانید image ها را با سرعت بالا دانلود کنید.

استفاده از مخزن آروان (پیشنهادی)

با توجه توضیحات درج شده درسایت آروان عینا مطابق روی قبلی است ولی آدرس سرور تغییر میکند

sudo bash -c 'cat > /etc/docker/daemon.json <<EOF
{
  "insecure-registries" : ["https://docker.arvancloud.ir"],
  "registry-mirrors": ["https://docker.arvancloud.ir"]
}
EOF'

استفاده از مخزن Docker.ir متعلق به پارس پک

فایل زیر را برای ویرایش باز کنید تا سرویس docker.ir را برای دانلود image ای داکر بودن تحریم دریافت کنید

اجرای دستور زیر و سپس وارد کردن رمز sudo سرور

sudo bash -c 'cat > /etc/docker/daemon.json <<EOF
{
  "registry-mirrors": ["https://registry.docker.ir"]
}
EOF'

سپس docker با دستورهای زیر ریست کنید.

docker logout
sudo systemctl daemon-reload
sudo systemctl restart docker

برای اینکه مطمن شویم که نصب ایمیج ها به خوبی انجام میشه دستور زیر را وارد کنید

sudo docker run hello-world

اگر به خوبی نصب شود خروجی مشابهه زیر دارد . این یعنی شما به سادگی میتوانید همه ایمیج های داکر را بدون دردسر نصب کنید.

اگر خواستید دستورات داکر را بدون نیاز به sudo اجرا کنید با ورود دستورات زیر امکان پذیر است .

از root با دستور exit خارج میشویم.

توجه :‌ حتما باید در کاربری که میخواهید دستورات بدون root اجرا شود لایگن باشید . مثلا ابتدا وارد کاربر ubuntu شوید و دستور زیر را وارد کنید . یعنی درون کاربر ubuntu میتوانید بدون ورود sudo docker ا اجرا کنید

sudo addgroup --system docker
sudo adduser $USER docker
newgrp docker

حالا میتوانید دستورات خود را بدون sudo ا جرا کنید

docker compose up -d

نکات کلی وردپرس

1-بخش functions

1-فهرست ها

برای تعریف فهرست اول این تکه خود را توی فایل functions.php قرار بدید

register_nav_menus(
		array(
			'primary' => __( 'Primary Menu', 'tailpress' ),
		)
	);

برای استفاده از تکه کد زیر استفاده کنید

	<?php
				wp_nav_menu(
					array(
						'container_id'    => 'primary-menu',
						'container_class' => '',
						'menu_class'      => '',
						'theme_location'  => 'primary',
						'li_class'        => ',
						'fallback_cb'     => false,
					)
				);
    ?>

2-افزودن ساپورت های معمولی برای تم مثل ماستوم لوگو , عکس برای پست و …..

 add_theme_support( 'custom-logo' );
add_theme_support( 'post-thumbnails' );
add_theme_support( 'align-wide' );
add_theme_support( 'wp-block-styles' );
add_theme_support( 'editor-styles' );
add_editor_style( 'css/editor-style.css' );

3-لینک کردن css

function tailpress_enqueue_scripts() {
	$theme = wp_get_theme();
	wp_enqueue_style( 'tailpress', tailpress_asset( 'css/app.css' ), array(), $theme->get( 'Version' ) );
}
add_action( 'wp_enqueue_scripts', 'tailpress_enqueue_scripts' );

4-گرفتن آدرس دایرکتوری

function tailpress_asset( $path ) {
	if ( wp_get_environment_type() === 'production' ) {
		return get_stylesheet_directory_uri() . '/' . $path;
	}
	return add_query_arg( 'time', time(),  get_stylesheet_directory_uri() . '/' . $path );
}

5-نشان ندادن یک نوع پست

function removelink() {
  if ( is_singular( 'page' ) ) {
	wp_redirect( home_url(), 301 );
	exit;
  }
}

6-تعریف ابزارک

if ( function_exists('register_sidebar') )
register_sidebar(array(
'name'          => 'about us text',
'before_widget' => '',
'after_widget'  => '',
'before_title'  => '',
'after_title'   => '',
),
);

برای استفاده از این قطه کد اسفاده کنید

<?php dynamic_sidebar( 'name' ); ?>

2-بخش صفحه اصلی

1-گرفتن پست با ایدی و ذخیره ان در متغیر

<?php 
$home = get_post(65); 
$about = get_post(154)
?>

2-گرفتن محتوای پست ذخیره شده

<!-- گرفتن تایتل  پستی که در متغیر ذخیره کردیم  -->
<h1><?= $home->post_title ?></h1>
<!-- گرفتن محتوای  پستی که در متغیر ذخیره کردیم  -->
<p><?= $home->post_content ?></p>

2-گرفتن کاستوم فیلد

<?= get_field('custom fild name'); ?>

3-بخش WP_Query ها

1- انتخاب با دسته

// از کتگوری با ایدی ۲۳ میاد ۸ تا پست اخرو نشون میده 
   $arr_posts = new WP_Query(array(
    'posts_per_page' => 8,
    'cat' => 23,
    )   );
 if ($arr_posts->have_posts()) :
    while ($arr_posts->have_posts()) :
        $arr_posts->the_post();
   //میره از این آدرس تمپلیت شما رو میخونه اینجا روش حلقه میزنه 
     get_template_part('template-parts/content', get_post_format());
    endwhile;
 endif;
 ?>

2- انتخاب با پست تایپ

  <?php
        // از پست تایپ وبلاگ میاد ۴ تا پست اخر و نشون میده 
		$arr_posts = new WP_Query(array(
			'posts_per_page' => 4,
             'post_type' => "webLog"			
		));
		if ($arr_posts->have_posts()) :
			while ($arr_posts->have_posts()) :
				$arr_posts->the_post();
				get_template_part('template-parts/webLog', get_post_format());
			endwhile;
		endif;
		?>

بخش WP_Query به همینجا محدود نمیشه خیلی اپشنای دیگه داره که میتونید برای مطالعه بیشتر از این لینک استفاده کنید

3-بخش توابع

<time datetime="<?php echo get_the_date( 'c' ); ?>" itemprop="datePublished"><?php echo get_the_date(); ?></time>
<!-- تابع گرفتن تاریخ -->
the_post_thumbnail('post-thumbnail', ['class' => '"w-full  shadow-xl rounded-xl', 'title' => 'Feature image']);	
<!-- تابع گرفتن عکس پست-->
<p>	<?= wp_strip_all_tags(get_the_content()) ?></p>
<!-- wp_strip_all_tags تابعیست برای حذف کردن تگ های قبل کانتنت  -->
the_excerpt()
<!-- گرفتن محتوا تا یک جای مشخص  -->
<a href="<?= esc_url(get_permalink()) ?>" 
<!-- تابعی برای گرفتن لینک پست -->

نحوه نوشتن From اول از یک Subquery در لاراول

سلام گاهی اوقات لازم است که query sql مشابه زیر داشته باشیم

select * from (select * from `shop_stores` where `shop_stores`.`deleted_at` is null) as `shop_stores` where `shop_stores`.`deleted_at` is null;

برای این منظور میتوانیم از متد subFrom در query builder لاراول استفاده کنیم.

        $firstQuery = stores::query();
        $secondQuery = stores::query();

        $secondQuery->fromSub($firstQuery,'shop_stores',function ($join){
            $join->on('shop_stores.id','=','latest_posts.id');
        });

        $secondQuery->dd();

نصب gitea در سرور مجازی ایران

با عرض سلام خدمت شما برنامه نویس گرامی

استفاده از سرویس های کنترل نسخه خارجی دارای مشکلاتی در موضوع تحریم است که با چالش هایی که در ایران هم وجود دارد لازم است که از سرویس جایگزین استفاده شود با توجه به تجربه ای که در استفاده و نصب gitlab داشته باید بگویم که به نسبت سنگینی که دارد خیلی به صرفه نیست معادل بهینه و کارامدتر Gitea است که من میخوام در این آموزش به شما تاکید کنم حتما از نسخه نصب Docker استفاده کنید و روش دستی را تا جایی که مقدور است استفاده نکند .

ابتدا از یکی از شرکتهای معتبر ایرانی یک VPS با سیستم عامل ubuntu 20 با ۲ هسته CPU و ۱ گیگ رم ترجیا ۲ گیگ خریداری کنید .

سپس لازم است که از سرویس شکن استفاده کنید ، باید ns های سرور را به ns های شکن تغییر دهید که بتوانید از docker استفاده کنید و بعد طبق آموزشی که خودم استفاده کرده ام پیش برید.

https://www.digitalocean.com/community/tutorials/how-to-install-gitea-on-ubuntu-using-docker

نحوه ایجاد استرس تست و benchmark از پروژه

یکی از بهترین ابزارها https://github.com/wg/wrk است که با دستور هایی میتواند به صورت همزمان میزان پاسخگویی به کاربران همزمان اپلکیشن شما را انجام دهد

لازم است که حتما در local این تست را بر اساس سخت افزاری که دارید انجام دهید

sudo apt-get install build-essential libssl-dev git -y 
git clone --depth 1 https://github.com/wg/wrk.git wrk
cd wrk 
sudo make 
# move the executable to somewhere in your PATH, ex: 
sudo cp wrk /usr/local/bin 

به طور مثال ۳۰ ثانیه در ۱۲ نخ و ۴۰۰ اتصال همزان با دستور زیر از ادرس زیر به اینصورت است

wrk -t12 -c400 -d30s http://127.0.0.1:8080/index.html

در واقع در تست زیر هرچه میزان درخواست بر ثانیه بیشتر باشد بهتر است

ارسال package public در npm

ابتدا در سایت npmjs.com عضو شوید

سپس در سیستم خود پروژه را که ایجاد کرده اید را روی صفحه github خود ارسال کنید

بعد با دستور npm init –scope=@vahidalvandi اسکوپ را تعریف کنید

بعد جهت ارسال به npm دستور npm publish –access public را ارسال کنید

 

خطای هنگام نصب پکیج local در composer

در صورتی که در نصب پکیج محلی خطای  in the lock file but not in remote repositories, make sure you avoid updating this package to keep the one from the lock file  را داشتید به دلیل عدم وجود فایل composer.json در root هر پکیج است مثلا باید در پروژه پکیچ های محلی در مسیر زیر باشد

packages/namevednor/base

درون base حتما باید composer.json باشد

همچنین دقت کنید که در composer.json اصلی که در root قرار دارد باید مسیر دهی به شکل زیر باشد

repositories": { "namevednor/base": { "type": "path", "url": "packages/namevednor/base" } }

require": {
"namevednor/site": "dev-master"
}