psr-4 네임스페이스 규칙

  • “class” 라는 용어는 class, interface, trait 등의 기타 유사한 구조를 말한다
  • 정규화 된 클래스 이름의 형식
    • \<NamespaceName>(\<SubNamespaceNames>)*\<ClassName>
    • 정규화 된 class 이름은 NamespaceName(공급자 네임스페이스) 라고하는 최상위 네임스페이스를 가져야한다. 회사명 아이디등 주로 사용한다. (MUST)
    • 정규화 된 class 이름은 하나 이상의 SubNamespaceNames를 가질 수 있다.(MAY)
    • 정규화 된 class 이름은 마지막 클래스 이름(terminating class name)을 가져야 한다.(MUST)
    • 밑줄(_)은 정규화 된 클래스 이름의 어느 부분에도 특별한 의미가 없다.
    • 정규화 된 클래스 이름의 알파벳 문자는 대소문자의 조합 일 수 있다 (MAY)
    • 모든 클래스 이름은 대소문자를 구분하여 참조해야한다.(MUST)
  • 정규화 된 class 이름에 해당하는 파일을 로드 할때
FULLY QUALIFIED CLASS NAMENAMESPACE PREFIXBASE DIRECTORYRESULTING FILE PATH
\Acme\Log\Writer\File_WriterAcme\Log\Writer./acme-log-writer/lib/./acme-log-writer/lib/File_Writer.php
\Aura\Web\Response\StatusAura\Web/path/to/aura-web/src//path/to/aura-web/src/Response/Status.php
\Symfony\Core\RequestSymfony\Core./vendor/Symfony/Core/./vendor/Symfony/Core/Request.php
\Zend\AclZend/usr/includes/Zend//usr/includes/Zend/Acl.php
네임스페이스 예제

  • 정규화 된 클래스 이름에서 선행 네임 스페이스 구분 기호(”)를 포함하지 않는 하나 이상의 상위 네임스페이스와 하위 네임스페이스로 구성된 (“namespace prefix”)는 적어도 하나의 base directory에 “대응”한다.
    Acme\Log\Writer : ./acme-log-writer/lib/
  • “Namespace prefix” 다음에 이어지는 하위 네임스페이스 이름은 “base directorty” 내의 하위 디렉토리에 해당하며 네임스페이스 구분 기호는 디렉토리 구분 기호를 나타낸다. 하위 디렉토리 이름은 하위 네임스페이스 이름의 대소문자와 일치해야 한다.
    \Aura\Web\Response\Status : /path/to/aura-web/src/Response/Status.php
  • 마지막에 존재하는 class이름은 .php 로 끝나는 파일 이름과 같아야 한다.
    \Aura\Web\Response\Status : /path/to/aura-web/src/Response/Status.php

postman 실행 오류

OpenFailedError: UpgradeError Dexie specification of currently installed DB version is missing

앱삭제 후 재설치 해도 문제 해결이 되지 않음

  1. ~/Library/Application Support로 이동
  2. postman 폴더명 백업 postman.old
  3. postman 재실행
  4. 정상작동

다시 ~/Library/Application Support으로 가보면 postman 디렉토리가 새로 생성된걸 확인 할수 있음

참고 : https://support.postman.com/hc/en-us/articles/360025359014-How-to-resolve-the-Could-not-open-Postman-error-

cURL

command line tool and library
for transferring data with URLs

지원 프로토콜

DICT, FILE, FTP, FTPS, Gopher, HTTP, HTTPS, IMAP, IMAPS, LDAP, LDAPS, MQTT, POP3, POP3S, RTMP, RTMPS, RTSP, SCP, SFTP, SMB, SMBS, SMTP, SMTPS, Telnet and TFTP. curl supports SSL certificates, HTTP POST, HTTP PUT, FTP uploading, HTTP form based upload, proxies, HTTP/2, HTTP/3, cookies, user+password authentication (Basic, Plain, Digest, CRAM-MD5, NTLM, Negotiate and Kerberos), file transfer resume, proxy tunneling and more.

기본사용

curl ipconfig.me

자주 사용하는 옵션

shortlong설명
-v–verbose내용을 자세하게 출력한다
-X–requestrequest method 지정
-H–headerrequest header 지정
-d–data사용자가 HTML 양식을 채우고 제출하는 방식과 동일한 POST 요청의 지정된 데이터를 HTTP 서버로 보냄
-o–output지정된 이름으로 파일저장

예제보기

#URL
POST /v1/synthesize HTTP/1.1
Host: kakaoi-newtone-openapi.kakao.com
Content-Type: application/xml
Authorization: KakaoAK {rest_api_key}
#REQUEST
curl -v -X POST "https://kakaoi-newtone-openapi.kakao.com/v1/synthesize" \
-H "Content-Type: application/xml" \
-H "Authorization: KakaoAK kkkkkkkkkkkkkkkkkkkkkkkkkkkkkkkk" \
-d '<speak>
그는 그렇게 말했습니다.
<voice name="MAN_DIALOG_BRIGHT">잘 지냈어? 나도 잘 지냈어.</voice>
<voice name="WOMAN_DIALOG_BRIGH" speechStyle="SS_ALT_FAST_1">금요일이 좋아요.</voice>
</speak>' > result.mp3

참조

같이보기

[laravel] This cache store does not support tagging 해결방법

태그가 지정된 캐시를 저장하고자 할때 ‘This cache store does not support tagging.’ 라는 에러가 발생했다.

코드 :

$articles = Cache::tags('article')->remember.env($cacheKey, now()->addMinutes(30), function () {
            return Article::latest()->paginate(10);
        });

문제해결:

캐시드라이버가 file 또는 database 에서는 태그기능을 지원하지 않는다.
.env 에서 CACHE_DRIVER값을 redis 또는 memcache또는 array로 변경한다.

#CACHE_DRIVER=file
CACHE_DRIVER=array

설정캐시를 날려 수정한 사항이 반영되도록 한다.

php artisan config:cache

만약 드라이버를 수정하지 않고 특정 위치에서만 사용하고 싶을때는 Cache파사드의 store메서드에 드라이버를 인자로 전달하면 된다.

        $articles = Cache::store('array')->tags('article')->remember($cacheKey, now()->addMinutes(30), function () {
            return Article::latest()->paginate(10);
        });

[apache2] a2enmod rewrite

환경

  • 우분투 18.04.2 LTS
  • Apache/2.4.29 (Ubuntu)

XE3에서 index.php에는 접근되는데 다른페이지는 404에러가 발생했다. 짧은 주소를 이용하는게 원인인가 싶어 서버설정을 찾아봤다.

apache2서버에서 짧은 주소를 사용하고 싶은경우 mod_rewrite모듈을 활성화 시켜야 한다.

sudo a2enmod rewrite

그리고 /etc/apache2/apache2.conf 에서 ‘AllowOverride all’ 로 변경한다.

<Directory /your/path>
        Options Indexes FollowSymLinks
        AllowOverride all
        Require all granted
</Directory>

아파치를 재시작해준다.

service apache2 restart

그래도 해결이 안되는 경우는 대부분 .htaccess 문제이니 파일을 확인해서 모듈 및 규칙이 올바르게 설정되어 있는지 확인한다.

[laravel] 다형성관계 시더작성하기

  • User모델은 Article 모델과 일대다 관계를 가진다.
  • Comment 모델은 Article 모델과 일대다 다형성 관계를 가진다.
  • Article은 제한이 없는 계층적인 댓글을 가진다.

0.테이블 스키마생성

Schema::create('users', function (Blueprint $table) {
            $table->id();
            $table->string('name');
            $table->string('email')->unique();
            $table->timestamp('email_verified_at')->nullable();
            $table->string('password');
            $table->rememberToken();
            $table->timestamps();
});

Schema::create('articles', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('user_id');
            $table->string('title');
            $table->text('content');
            $table->timestamps();
            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
        });

Schema::create('comments', function (Blueprint $table) {
            $table->id();
            $table->unsignedBigInteger('user_id');
            $table->unsignedBigInteger('parent_id')->nullable();
            $table->text('content');
            $table->string('commentable_type');
            $table->unsignedBigInteger('commentable_id');
            $table->timestamps();

            $table->foreign('user_id')->references('id')->on('users')->onDelete('cascade');
            $table->foreign('parent_id')->references('id')->on('comments');
        });

1. 모델간 관계 정의

User 모델 :

    public function articles()
    {
        return $this->hasMany(Article::class);
    }

    public function comments()
    {
        return $this->hasMany(Comment::class);
    }

Article 모델 :

protected $fillable = ['user_id', 'title', 'content'];

public function user()
    {
        return $this->belongsTo(User::class);
    }

    public function comments()
    {
        return $this->morphMany(Comment::class, 'commentable');
    }

Comment 모델:

protected $fillable = ['content', 'user_id', 'commentable_type', 'commentable_id', 'parent_id'];

public function commentable()
    {
        return $this->morphTo();
    }

    public function parent()
    {
        return $this->belongsTo(Comment::class, 'parent_id');
    }

    public function replies()
    {
        return $this->hasMany(Comment::class, 'parent_id');
    }

    public function article()
    {
        return $this->belongsTo(Article::class, 'commentable_id');
    }

    public function user()
    {
        return $this->belongsTo(User::class);
    }

엘로퀀트는 comments 테이블의 외래키를 comment_id로 자동으로 추정하기 때문에 메서드 인자에 ‘parent_id’를 전달해서 외래키를 지정했다.

2.시더에 사용할 팩토리 작성

UserFactory :

$factory->define(User::class, function (Faker $faker) {
    return [
        'name' => $faker->name,
        'email' => $faker->unique()->safeEmail,
        'email_verified_at' => now(),
        'password' => '$2y$10$92IXUNpkjO0rOQ5byMi.Ye4oKoEa3Ro9llC/.og/at2.uheWG/igi', // password
        'remember_token' => Str::random(10),
    ];
});

ArticleFactory :

$factory->define(Article::class, function (Faker $faker) {
    return [
        'title' => $faker->sentence,
        'content' => $faker->paragraph,
    ];
});

Article은 User와 관계가 정의 되어있기 때문에 user_id를 따로 지정하지 않아도 자동으로 시더를 통해 입력된다.

CommentFactory :

$factory->define(Comment::class, function (Faker $faker) {
    $userIds = App\User::all()->pluck('id')->toArray();
    return [
        'content' => $faker->paragraph(),
        'user_id' => $faker->randomElement($userIds),
    ];
});

마찬가지로 ‘commentable_type’, ‘commentabe_id’를 지정하지 않는 이유는 위와 같다.

‘paretn_id’ 는 null을 허용한다. 이 값이 지정되어 있지 않으면 최상위 댓글로 간주한다. ‘CommentFactory’ 에는 이 값을 비워두어 최상위 댓글을 생성하게 한다. 후에 시더에서 make 메서드에 ‘parent_id’ 를 전달해 계층적인 댓글 구조를 만들어 준다.

3.시더작성

UsersTableSeeder :

    public function run()
    {
        factory(App\User::class, 10)->create()->each(function($user){
            $user->articles()->createMany(factory(App\Article::class, 3)->make()->toArray());
        });
    }

CommentsTableSeeder :

    public function run()
    {
        $faker = Faker\Factory::create();
        $articles = App\Article::all();
        //최상위 댓글 생성
        $articles->each(function($article){
            $article->comments()->createMany(factory(App\Comment::class, 3)->make()->toArray());
        });
       //계층적 댓글 생성
        $articles->each(function($article) use ($faker){
        for($i=0; $i<10; $i++)
            {
                $commentIds = $article->comments()->pluck('id')->toArray();
                $article->comments()->create(factory(App\Comment::class)->make(
                    ['parent_id' => $faker->randomElement($commentIds)]
                )->toArray());
            }
        });
    }

계층적 댓글 생성 부분에서 make 메서드를 보면 ‘CommentFactory’에서 지정하지 않은 ‘parent_id’값을 전달해 줌으로써 재귀적인 댓글 구조를 가질수 있게 한다.

[리눅스] 자주 찾아보는 것들

Linux 표준 스트림과 리다이렉션

https://hongsii.github.io/2018/06/25/linux-standard-streams/

파이프에 대한 이해

https://gracefulprograming.tistory.com/m/92

쉘스크립트 문법

https://www.fun-coding.org/linux_basic3.html

함수작성하기

https://net711.tistory.com/m/entry/배쉬-쉘-함수

mysql 백업스크립트

https://kugancity.tistory.com/m/entry/mysql-데이터베이스-백업-스크립트

cron 사용하기

https://webdir.tistory.com/174